diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java index 3ec22b87ea..ee7cc7e5da 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java @@ -18,7 +18,7 @@ */ package org.jclouds.cloudstack.config; -import static org.jclouds.rest.config.BinderUtils.bindHttpApi; +import static org.jclouds.rest.config.BinderUtils.bindSyncToAsyncHttpApi; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -207,9 +207,9 @@ public class CloudStackRestClientModule extends RestClientModule>builder() + .add(MappedAuthenticationApiModule.class) .add(KeystoneAuthenticationModule.class) .add(ZoneModule.class) .add(CinderParserModule.class) diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/AuthenticationApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/AuthenticationApi.java index d62bc67788..8fc7aa355f 100644 --- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/AuthenticationApi.java +++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/AuthenticationApi.java @@ -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. *

* - * @see AuthenticationAsyncApi - * @see * @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); } diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/AuthenticationAsyncApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/AuthenticationAsyncApi.java index 02dd7c590e..6113aed85c 100644 --- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/AuthenticationAsyncApi.java +++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/AuthenticationAsyncApi.java @@ -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 * @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) diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java index 003be876e8..7ddbdab18b 100644 --- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java +++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java @@ -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.>builder() + .add(MappedAuthenticationApiModule.class) .add(KeystoneAuthenticationModule.class) .add(KeystoneAdminURLModule.class) .add(KeystoneParserModule.class) diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/AuthenticationApiModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/AuthenticationApiModule.java new file mode 100644 index 0000000000..71424604d1 --- /dev/null +++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/AuthenticationApiModule.java @@ -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); + } + +} diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java index c1e201211f..0b2099dc21 100644 --- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java +++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java @@ -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} *

  • add the above annotation to any {@link AsyncApi} classes by placing it on the type. ex. * {@code @Endpoint(CloudDNS.class)}
  • - *
  • add the following to your {@link RestClientModule}
  • + *
  • add the following to your {@link org.jclouds.rest.config.RestClientModule}
  • * *
         * bind(new TypeLiteral<Supplier<URI>>() {
    @@ -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);
        }
     
        /**
    diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/MappedAuthenticationApiModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/MappedAuthenticationApiModule.java
    new file mode 100644
    index 0000000000..0a49f1566e
    --- /dev/null
    +++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/MappedAuthenticationApiModule.java
    @@ -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.bindSyncToAsyncHttpApi;
    +
    +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
    +      bindSyncToAsyncHttpApi(binder(), AuthenticationApi.class, AuthenticationAsyncApi.class);
    +   }
    +
    +}
    diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/config/ProviderModuleExpectTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/config/ProviderModuleExpectTest.java
    index 21705c99f9..7cbc64db5b 100644
    --- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/config/ProviderModuleExpectTest.java
    +++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/config/ProviderModuleExpectTest.java
    @@ -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 {
     
        @Retention(RUNTIME)
    -   @Target(TYPE)
    +   @Target(METHOD)
        @Qualifier
        static @interface DNS {
        }
     
    -   @ConfiguresRestClient
    -   public static class DNSRestClientModule extends RestClientModule {
    +   @ConfiguresHttpApi
    +   public static class DNSHttpApiModule extends HttpApiModule {
    +
           @Override
           public void configure() {
    -         bind(new TypeLiteral>() {}).annotatedWith(DNS.class).to(new TypeLiteral>() {});
              bind(DateAdapter.class).to(Iso8601DateAdapter.class);
              super.configure();
           }
    -   }
     
    -   static interface DNSApi extends Closeable {
    -      boolean zoneExists(@PathParam("zoneName") String zoneName);
    +      @Provides
    +      @Singleton
    +      @DNS
    +      protected Supplier 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 zoneExists(@PathParam("zoneName") String zoneName);
    +      boolean zoneExists(@PathParam("zoneName") String zoneName);
        }
     
        public void testDNSEndpointApplied() {
    @@ -86,7 +111,7 @@ public class ProviderModuleExpectTest extends BaseRestApiExpectTest {
     
           @Override
           public Builder toBuilder() {
    @@ -102,31 +127,29 @@ public class ProviderModuleExpectTest extends BaseRestApiExpectTest {
    +      public static class Builder extends BaseHttpApiMetadata.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.> 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.>builder()
    +                                        .add(AuthenticationApiModule.class)
    +                                        .add(KeystoneAuthenticationModule.class)
    +                                        .add(RegionModule.class)
    +                                        .add(DNSHttpApiModule.class).build());
              }
     
              @Override
    diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApiMetadata.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApiMetadata.java
    index f5a8a92aee..d112814f09 100644
    --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApiMetadata.java
    +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApiMetadata.java
    @@ -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.>builder()
    +                                     .add(MappedAuthenticationApiModule.class)
                                          .add(KeystoneAuthenticationModule.class)
                                          .add(ZoneModule.class)
                                          .add(NovaParserModule.class)
    diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityApiMetadata.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityApiMetadata.java
    index edf8f4d40d..a7372c7ded 100644
    --- a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityApiMetadata.java
    +++ b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityApiMetadata.java
    @@ -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.SyncToAsyncCloudIdentityAuthenticationApiModule;
     
     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.>builder()
    +                                     .add(SyncToAsyncCloudIdentityAuthenticationApiModule.class)
                                          .add(CloudIdentityAuthenticationModule.class)
                                          .add(KeystoneAdminURLModule.class)
                                          .add(KeystoneParserModule.class)
    diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationApi.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationApi.java
    index ed3d03eedd..a86bddae39 100644
    --- a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationApi.java
    +++ b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationApi.java
    @@ -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.
      * 

    * - * @see AuthenticationAsyncApi - * @see * @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); } diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationAsyncApi.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationAsyncApi.java index c4c03a38f1..acb2dbbe34 100644 --- a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationAsyncApi.java +++ b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationAsyncApi.java @@ -43,7 +43,10 @@ import com.google.common.util.concurrent.ListenableFuture; * @see * @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 { /** diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationApiModule.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationApiModule.java new file mode 100644 index 0000000000..7f60d3d7e8 --- /dev/null +++ b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationApiModule.java @@ -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; + } +} diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationModule.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationModule.java index d56fff2535..2b5f7a2821 100644 --- a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationModule.java +++ b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationModule.java @@ -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> authenticationMethods(Injector i) { Builder> fns = ImmutableSet.> builder(); diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/SyncToAsyncCloudIdentityAuthenticationApiModule.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/SyncToAsyncCloudIdentityAuthenticationApiModule.java new file mode 100644 index 0000000000..07782db83e --- /dev/null +++ b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/SyncToAsyncCloudIdentityAuthenticationApiModule.java @@ -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.bindSyncToAsyncHttpApi; + +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 SyncToAsyncCloudIdentityAuthenticationApiModule extends AbstractModule { + + @Override + protected void configure() { + // AuthenticationApi is used directly for filters and retry handlers, so + // let's bind it explicitly + bindSyncToAsyncHttpApi(binder(), CloudIdentityAuthenticationApi.class, CloudIdentityAuthenticationAsyncApi.class); + } + + @Provides + private AuthenticationApi provideAuthenticationApi(CloudIdentityAuthenticationApi in) { + return in; + } + + @Provides + private AuthenticationAsyncApi provideAuthenticationAsyncApi(CloudIdentityAuthenticationAsyncApi in) { + return in; + } + +} diff --git a/apis/rackspace-cloudloadbalancers/pom.xml b/apis/rackspace-cloudloadbalancers/pom.xml index 366de205ef..1cfc325be5 100644 --- a/apis/rackspace-cloudloadbalancers/pom.xml +++ b/apis/rackspace-cloudloadbalancers/pom.xml @@ -37,8 +37,8 @@ https://identity.api.rackspacecloud.com/v2.0/ 1 - ${test.rackspace.identity} - ${test.rackspace.credential} + ${test.rackspace-us.identity} + ${test.rackspace-us.credential} org.jclouds.rackspace.cloudloadbalancers*;version="${project.version}" org.jclouds*;version="${project.version}",* diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApi.java index edd433d068..634ba49d10 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApi.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApi.java @@ -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. *

    * - * @see CloudLoadBalancersAsyncApi - * @author Adrian Cole + * @author Everett Toews */ public interface CloudLoadBalancersApi extends Closeable { /** @@ -58,14 +57,14 @@ public interface CloudLoadBalancersApi extends Closeable { Set 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( diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApiMetadata.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApiMetadata.java index 64a33638f8..f5740f8ac7 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApiMetadata.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApiMetadata.java @@ -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> CONTEXT_TOKEN = new TypeToken>() { - private static final long serialVersionUID = 1L; - }; +public class CloudLoadBalancersApiMetadata extends BaseHttpApiMetadata { @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 { + public static class Builder extends BaseHttpApiMetadata.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.> of( - CloudIdentityAuthenticationModule.class, - ZoneModule.class, - CloudLoadBalancersRestClientModule.class, - CloudLoadBalancersLoadBalancerContextModule.class)); + .defaultModules(ImmutableSet.>builder() + .add(CloudIdentityAuthenticationApiModule.class) + .add(CloudIdentityAuthenticationModule.class) + .add(ZoneModule.class) + .add(CloudLoadBalancersHttpApiModule.class) + .add(CloudLoadBalancersLoadBalancerContextModule.class).build()); } @Override diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersAsyncApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersAsyncApi.java deleted file mode 100644 index dca10a6602..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersAsyncApi.java +++ /dev/null @@ -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. - *

    - * - * @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 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); -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/config/CloudLoadBalancersHttpApiModule.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/config/CloudLoadBalancersHttpApiModule.java new file mode 100644 index 0000000000..3c1629ca65 --- /dev/null +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/config/CloudLoadBalancersHttpApiModule.java @@ -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 { + + @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); + } +} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/config/CloudLoadBalancersRestClientModule.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/config/CloudLoadBalancersRestClientModule.java deleted file mode 100644 index 921ba16442..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/config/CloudLoadBalancersRestClientModule.java +++ /dev/null @@ -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 { - - public static final Map, Class> DELEGATE_MAP = ImmutableMap., 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); - } -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/AccessRuleApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/AccessRuleApi.java index 4d32b23fc2..c8db030330 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/AccessRuleApi.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/AccessRuleApi.java @@ -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. *

    * - * @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 accessRules); + @Named("accessrule:create") + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Fallback(VoidOnNotFoundOr404.class) + @Path("/accesslist") + void create(@WrapWith("accessList") Iterable accessRules); /** * List the AccessRules. */ + @Named("accessrule:list") + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Fallback(EmptyPagedIterableOnNotFoundOr404.class) + @SelectJson("accessList") + @Path("/accesslist") Iterable 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 ids); + @Named("accessrule:delete") + @DELETE + @Fallback(FalseOnNotFoundOr404.class) + @Path("/accesslist") + @Consumes("*/*") + boolean delete(@QueryParam("id") Iterable 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(); } \ No newline at end of file diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/AccessRuleAsyncApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/AccessRuleAsyncApi.java deleted file mode 100644 index 6a4c872809..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/AccessRuleAsyncApi.java +++ /dev/null @@ -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. - *

    - * - * @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 create(@WrapWith("accessList") Iterable accessRules); - - /** - * @see AccessRuleApi#list() - */ - @Named("accessrule:list") - @GET - @Consumes(MediaType.APPLICATION_JSON) - @Fallback(EmptyPagedIterableOnNotFoundOr404.class) - @SelectJson("accessList") - @Path("/accesslist") - ListenableFuture> list(); - - /** - * @see AccessRuleApi#delete(int) - */ - @Named("accessrule:delete") - @DELETE - @Fallback(FalseOnNotFoundOr404.class) - @Path("/accesslist/{id}") - @Consumes("*/*") - ListenableFuture delete(@PathParam("id") int id); - - /** - * @see AccessRuleApi#delete(Iterable) - */ - @Named("accessrule:delete") - @DELETE - @Fallback(FalseOnNotFoundOr404.class) - @Path("/accesslist") - @Consumes("*/*") - ListenableFuture delete(@QueryParam("id") Iterable ids); - - /** - * @see AccessRuleApi#deleteAll() - */ - @Named("accessrule:delete") - @DELETE - @Fallback(FalseOnNotFoundOr404.class) - @Path("/accesslist") - @Consumes("*/*") - ListenableFuture deleteAll(); -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ConnectionApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ConnectionApi.java index 1aa65603b3..cca0298760 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ConnectionApi.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ConnectionApi.java @@ -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. *

    * - * @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(); } \ No newline at end of file diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ConnectionAsyncApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ConnectionAsyncApi.java deleted file mode 100644 index e50fd71679..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ConnectionAsyncApi.java +++ /dev/null @@ -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. - *

    - * - * @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 createOrUpdateConnectionThrottle( - @WrapWith("connectionThrottle") ConnectionThrottle connectionThrottle); - - /** - * @see ConnectionApi#getConnectionThrottle() - */ - @Named("connectionthrottle:get") - @GET - @Consumes(MediaType.APPLICATION_JSON) - @SelectJson("connectionThrottle") - @Fallback(NullOnNotFoundOr404.class) - @Path("/connectionthrottle") - ListenableFuture getConnectionThrottle(); - - /** - * @see ConnectionApi#deleteConnectionThrottle() - */ - @Named("connectionthrottle:delete") - @DELETE - @Fallback(FalseOnNotFoundOr422.class) - @Path("/connectionthrottle") - @Consumes("*/*") - ListenableFuture deleteConnectionThrottle(); - - /** - * @see ConnectionApi#isConnectionLogging() - */ - @Named("connectionlogging:state") - @GET - @Consumes(MediaType.APPLICATION_JSON) - @ResponseParser(ParseNestedBoolean.class) - @Fallback(FalseOnNotFoundOr404.class) - @Path("/connectionlogging") - ListenableFuture 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 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 disableConnectionLogging(); -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ContentCachingApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ContentCachingApi.java index 0f28ed363c..63f315e1a3 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ContentCachingApi.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ContentCachingApi.java @@ -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. *

    * - * @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(); } \ No newline at end of file diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ContentCachingAsyncApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ContentCachingAsyncApi.java deleted file mode 100644 index 47ad77c44d..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ContentCachingAsyncApi.java +++ /dev/null @@ -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. - *

    - * - * @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 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 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 disable(); -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ErrorPageApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ErrorPageApi.java index dbb9df1507..a55129e12a 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ErrorPageApi.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ErrorPageApi.java @@ -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. *

    * - * @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(); } \ No newline at end of file diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ErrorPageAsyncApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ErrorPageAsyncApi.java deleted file mode 100644 index 2d94d7a121..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ErrorPageAsyncApi.java +++ /dev/null @@ -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. - *

    - * - * @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 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 get(); - - /** - * @see ErrorPageApi#delete() - */ - @Named("errorpage:delete") - @DELETE - @Consumes(MediaType.WILDCARD) - @Fallback(FalseOnNotFoundOr404.class) - @Path("/errorpage") - ListenableFuture delete(); -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/HealthMonitorApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/HealthMonitorApi.java index 72f6ff538e..d3b581d7dc 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/HealthMonitorApi.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/HealthMonitorApi.java @@ -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. *

    - * @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(); } \ No newline at end of file diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/HealthMonitorAsyncApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/HealthMonitorAsyncApi.java deleted file mode 100644 index f99cb587fa..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/HealthMonitorAsyncApi.java +++ /dev/null @@ -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. - *

    - * - * @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 createOrUpdate(@WrapWith("healthMonitor") HealthMonitor healthMonitor); - - /** - * @see HealthMonitorApi#get() - */ - @Named("healthmonitor:get") - @GET - @Consumes(MediaType.APPLICATION_JSON) - @SelectJson("healthMonitor") - @Fallback(NullOnNotFoundOr404.class) - @Path("/healthmonitor") - ListenableFuture get(); - - /** - * @see HealthMonitorApi#delete() - */ - @Named("healthmonitor:delete") - @DELETE - @Fallback(FalseOnNotFoundOr422.class) - @Path("/healthmonitor") - @Consumes("*/*") - ListenableFuture delete(); -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/LoadBalancerApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/LoadBalancerApi.java index cedc29ecbf..5884ca6740 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/LoadBalancerApi.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/LoadBalancerApi.java @@ -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. *

    * - * @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 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 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 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 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 metadataIds); + @Named("lb:deletemetadata") + @DELETE + @Fallback(FalseOnNotFoundOr404.class) + @Consumes("*/*") + @Path("/loadbalancers/{id}/metadata") + boolean deleteMetadata(@PathParam("id") int id, + @QueryParam("id") Iterable metadataIds); } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/LoadBalancerAsyncApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/LoadBalancerAsyncApi.java deleted file mode 100644 index 1c406681a5..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/LoadBalancerAsyncApi.java +++ /dev/null @@ -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. - *

    - * - * @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 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 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> list(); - - /** - * @see LoadBalancerApi#list(PaginationOptions) - */ - @Named("lb:list") - @GET - @ResponseParser(ParseLoadBalancers.class) - @Consumes(MediaType.APPLICATION_JSON) - @Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class) - @Path("/loadbalancers") - ListenableFuture> 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 get(@PathParam("id") int id); - - /** - * @see LoadBalancerApi#delete(int) - */ - @Named("lb:delete") - @DELETE - @Fallback(VoidOnNotFoundOr404.class) - @Path("/loadbalancers/{id}") - @Consumes("*/*") - ListenableFuture 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 createMetadata( - @PathParam("id") int id, - @BinderParam(BindMetadataToJsonPayload.class) Map metadata); - - /** - * @see LoadBalancerApi#getMetadata(int) - */ - @Named("lb:getmetadata") - @GET - @Consumes(MediaType.APPLICATION_JSON) - @ResponseParser(ParseMetadata.class) - @Fallback(EmptyMapOnNotFoundOr404.class) - @Path("/loadbalancers/{id}/metadata") - ListenableFuture 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 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 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 deleteMetadata(@PathParam("id") int id, - @QueryParam("id") Iterable metadataIds); -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/NodeApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/NodeApi.java index 325f377ee5..0a445a94e7 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/NodeApi.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/NodeApi.java @@ -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. *

    * - * @see NodeAsyncApi * @author Everett Toews */ +@RequestFilters(AuthenticateRequest.class) public interface NodeApi { /** * Add a new node with the configuration defined by the request. */ - Set add(Iterable addNodes); + @Named("node:add") + @POST + @SelectJson("nodes") + @Consumes(MediaType.APPLICATION_JSON) + @Fallback(NullOnNotFoundOr404.class) + @Path("/nodes") + Set add(@WrapWith("nodes") Iterable 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 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 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 ids); + @Named("node:remove") + @DELETE + @Path("/nodes") + @Fallback(VoidOnNotFoundOr404.class) + @Consumes("*/*") + void remove(@QueryParam("id") Iterable 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 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 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 metadataIds); + @Named("node:deletemetadata") + @DELETE + @Fallback(FalseOnNotFoundOr404.class) + @Consumes("*/*") + @Path("/nodes/{id}/metadata") + boolean deleteMetadata(@PathParam("id") int id, + @QueryParam("id") Iterable metadataIds); } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/NodeAsyncApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/NodeAsyncApi.java deleted file mode 100644 index fd542a94f0..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/NodeAsyncApi.java +++ /dev/null @@ -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. - *

    - * - * @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> add(@WrapWith("nodes") Iterable addNodes); - - /** - * @see NodeApi#update(int, UpdateNode) - */ - @Named("node:update") - @PUT - @Consumes(MediaType.APPLICATION_JSON) - @Path("/nodes/{id}") - ListenableFuture 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> list(); - - /** - * @see NodeApi#list(PaginationOptions) - */ - @Named("node:list") - @GET - @ResponseParser(ParseNodes.class) - @Consumes(MediaType.APPLICATION_JSON) - @Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class) - @Path("/nodes") - ListenableFuture> 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 get(@PathParam("id") int id); - - /** - * @see NodeApi#remove(int) - */ - @Named("node:remove") - @DELETE - @Path("/nodes/{id}") - @Fallback(VoidOnNotFoundOr404.class) - @Consumes("*/*") - ListenableFuture remove(@PathParam("id") int id); - - /** - * @see NodeApi#remove(Set) - */ - @Named("node:remove") - @DELETE - @Path("/nodes") - @Fallback(VoidOnNotFoundOr404.class) - @Consumes("*/*") - ListenableFuture remove(@QueryParam("id") Iterable 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 createMetadata( - @PathParam("id") int id, - @BinderParam(BindMetadataToJsonPayload.class) Map metadata); - - /** - * @see NodeApi#getMetadata(int) - */ - @Named("node:getmetadata") - @GET - @Consumes(MediaType.APPLICATION_JSON) - @ResponseParser(ParseMetadata.class) - @Fallback(EmptyMapOnNotFoundOr404.class) - @Path("/nodes/{id}/metadata") - ListenableFuture 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 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 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 deleteMetadata(@PathParam("id") int id, - @QueryParam("id") Iterable metadataIds); -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ReportApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ReportApi.java index fe1981c19d..0222ae7e5b 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ReportApi.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ReportApi.java @@ -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. *

    - * @see ReportAsyncApi * @author Everett Toews */ +@RequestFilters(AuthenticateRequest.class) public interface ReportApi { /** * List billable load balancers for the given date range. */ - PagedIterable 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 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 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 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 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 listLoadBalancerUsage(PaginationOptions options); /** * Current usage represents all usage recorded within the preceding 24 hours. */ - PagedIterable 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 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 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 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 listAlgorithms(); } \ No newline at end of file diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ReportAsyncApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ReportAsyncApi.java deleted file mode 100644 index b43662c141..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ReportAsyncApi.java +++ /dev/null @@ -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. - *

    - * - * @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> 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> listBillableLoadBalancers(PaginationOptions options); - - /** - * @see ReportApi#getHistoricalUsage(Date, Date) - */ - @Named("report:list") - @GET - @Consumes(MediaType.APPLICATION_JSON) - @Fallback(NullOnNotFoundOr404.class) - @Path("/loadbalancers/usage") - ListenableFuture 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> 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> 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> 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> listCurrentLoadBalancerUsage(PaginationOptions options); - - /** - * @see ReportApi#getLoadBalancerStats(int) - */ - @Named("report:list") - @GET - @Consumes(MediaType.APPLICATION_JSON) - @Fallback(NullOnNotFoundOr404.class) - @Path("/loadbalancers/{id}/stats") - ListenableFuture 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> listProtocols(); - - /** - * @see ReportApi#listAlgorithms() - */ - @Named("report:list") - @GET - @Consumes(MediaType.APPLICATION_JSON) - @ResponseParser(ParseAlgorithms.class) - @Fallback(NullOnNotFoundOr404.class) - @Path("/loadbalancers/algorithms") - ListenableFuture> listAlgorithms(); -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SSLTerminationApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SSLTerminationApi.java index 54cdcb41a9..2d995e3f62 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SSLTerminationApi.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SSLTerminationApi.java @@ -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. * * - * @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(); } \ No newline at end of file diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SSLTerminationAsyncApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SSLTerminationAsyncApi.java deleted file mode 100644 index fc8d678f7b..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SSLTerminationAsyncApi.java +++ /dev/null @@ -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. - *

    - * - * @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 createOrUpdate(@WrapWith("sslTermination") SSLTermination sslTermination); - - /** - * @see SSLTerminationApi#get() - */ - @Named("ssltermination:get") - @GET - @Consumes(MediaType.APPLICATION_JSON) - @SelectJson("sslTermination") - @Fallback(NullOnNotFoundOr404.class) - @Path("/ssltermination") - ListenableFuture get(); - - /** - * @see SSLTerminationApi#delete() - */ - @Named("ssltermination:delete") - @DELETE - @Fallback(FalseOnNotFoundOr422.class) - @Path("/ssltermination") - @Consumes("*/*") - ListenableFuture delete(); -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SessionPersistenceApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SessionPersistenceApi.java index 1588c5a7a1..7a013ec415 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SessionPersistenceApi.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SessionPersistenceApi.java @@ -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(); } \ No newline at end of file diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SessionPersistenceAsyncApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SessionPersistenceAsyncApi.java deleted file mode 100644 index 7ef1eb1f8e..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SessionPersistenceAsyncApi.java +++ /dev/null @@ -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. - *

    - * - * @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 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 create(@PayloadParam("sessionPersistence") SessionPersistence sessionPersistence); - - /** - * @see SessionPersistenceApi#delete() - */ - @Named("sessionpersistence:delete") - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - @Fallback(VoidOnNotFoundOr404.class) - @Path("/sessionpersistence") - ListenableFuture delete(); -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/VirtualIPApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/VirtualIPApi.java index e4d33fb9dd..a1fcdb51c1 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/VirtualIPApi.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/VirtualIPApi.java @@ -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. *

    * - * @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 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 ids); + @Named("virtualip:delete") + @DELETE + @Fallback(FalseOnNotFoundOr404.class) + @Path("/virtualips") + @Consumes("*/*") + boolean delete(@QueryParam("id") Iterable ids); } \ No newline at end of file diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/VirtualIPAsyncApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/VirtualIPAsyncApi.java deleted file mode 100644 index 4653f2f00f..0000000000 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/VirtualIPAsyncApi.java +++ /dev/null @@ -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. - *

    - * - * @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 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> list(); - - /** - * @see VirtualIPApi#delete(int) - */ - @Named("virtualip:delete") - @DELETE - @Fallback(FalseOnNotFoundOr404.class) - @Path("/virtualips/{id}") - @Consumes("*/*") - ListenableFuture delete(@PathParam("id") int id); - - /** - * @see VirtualIPApi#delete(Iterable) - */ - @Named("virtualip:delete") - @DELETE - @Fallback(FalseOnNotFoundOr404.class) - @Path("/virtualips") - @Consumes("*/*") - ListenableFuture delete(@QueryParam("id") Iterable ids); -} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/functions/ParseLoadBalancerUsages.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/functions/ParseLoadBalancerUsages.java index e418b476e3..0279be0d68 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/functions/ParseLoadBalancerUsages.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/functions/ParseLoadBalancerUsages.java @@ -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 { } } - public static class ToPagedIterable extends CallerArg0ToPagedIterable { + public static class ToPagedIterable extends Arg0ToPagedIterable.FromCaller { private final CloudLoadBalancersApi api; @@ -71,7 +72,8 @@ public class ParseLoadBalancerUsages extends ParseJson { } @Override - protected Function> markerToNextForCallingArg0(final String zone) { + protected Function> markerToNextForArg0(Optional arg0) { + String zone = arg0.isPresent() ? arg0.get().toString() : null; final ReportApi reportApi = api.getReportApiForZone(zone); return new Function>() { diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/functions/ParseLoadBalancers.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/functions/ParseLoadBalancers.java index 56ea07c536..d5f2e2ab11 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/functions/ParseLoadBalancers.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/functions/ParseLoadBalancers.java @@ -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 { + public static class ToPagedIterable extends Arg0ToPagedIterable.FromCaller { private final CloudLoadBalancersApi api; @@ -102,7 +103,8 @@ public class ParseLoadBalancers implements Function> markerToNextForCallingArg0(final String zone) { + protected Function> markerToNextForArg0(Optional arg0) { + String zone = arg0.isPresent() ? arg0.get().toString() : null; final LoadBalancerApi loadBalancerApi = api.getLoadBalancerApiForZone(zone); return new Function>() { diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/functions/ParseNodes.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/functions/ParseNodes.java index e7745cef0d..14914d3b52 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/functions/ParseNodes.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/functions/ParseNodes.java @@ -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 { super(json, new TypeLiteral() { }); } - public static class ToPagedIterable extends CallerArg0ToPagedIterable { + public static class ToPagedIterable extends Arg0ToPagedIterable.FromCaller { private final CloudLoadBalancersApi api; private int lbId; @@ -86,7 +87,8 @@ public class ParseNodes extends ParseJson { } @Override - protected Function> markerToNextForCallingArg0(final String zone) { + protected Function> markerToNextForArg0(Optional arg0) { + String zone = arg0.isPresent() ? arg0.get().toString() : null; final NodeApi nodeApi = api.getNodeApiForZoneAndLoadBalancer(zone, lbId); return new Function>() { diff --git a/apis/route53/src/main/java/org/jclouds/route53/Route53Api.java b/apis/route53/src/main/java/org/jclouds/route53/Route53Api.java index 4909226ea9..43d11db393 100644 --- a/apis/route53/src/main/java/org/jclouds/route53/Route53Api.java +++ b/apis/route53/src/main/java/org/jclouds/route53/Route53Api.java @@ -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 *

    * - * @see Route53AsyncApi * @see * @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); } diff --git a/apis/route53/src/main/java/org/jclouds/route53/Route53ApiMetadata.java b/apis/route53/src/main/java/org/jclouds/route53/Route53ApiMetadata.java index f64443c835..1785e22dfd 100644 --- a/apis/route53/src/main/java/org/jclouds/route53/Route53ApiMetadata.java +++ b/apis/route53/src/main/java/org/jclouds/route53/Route53ApiMetadata.java @@ -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> CONTEXT_TOKEN = new TypeToken>() { - private static final long serialVersionUID = 1L; - }; +public class Route53ApiMetadata extends BaseHttpApiMetadata { @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 { + public static class Builder extends BaseHttpApiMetadata.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 diff --git a/apis/route53/src/main/java/org/jclouds/route53/Route53AsyncApi.java b/apis/route53/src/main/java/org/jclouds/route53/Route53AsyncApi.java deleted file mode 100644 index fac0d408f5..0000000000 --- a/apis/route53/src/main/java/org/jclouds/route53/Route53AsyncApi.java +++ /dev/null @@ -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 - *

    - * - * @see - * @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 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); -} diff --git a/apis/route53/src/main/java/org/jclouds/route53/config/Route53RestClientModule.java b/apis/route53/src/main/java/org/jclouds/route53/config/Route53HttpApiModule.java similarity index 67% rename from apis/route53/src/main/java/org/jclouds/route53/config/Route53RestClientModule.java rename to apis/route53/src/main/java/org/jclouds/route53/config/Route53HttpApiModule.java index 613bf54ed2..b7b930f9f9 100644 --- a/apis/route53/src/main/java/org/jclouds/route53/config/Route53RestClientModule.java +++ b/apis/route53/src/main/java/org/jclouds/route53/config/Route53HttpApiModule.java @@ -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 { - public static final Map, Class> DELEGATE_MAP = ImmutableMap., 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 { + public Route53HttpApiModule() { } @Provides diff --git a/apis/route53/src/main/java/org/jclouds/route53/features/HostedZoneApi.java b/apis/route53/src/main/java/org/jclouds/route53/features/HostedZoneApi.java index 36a01989ce..1cfc8ea9c4 100644 --- a/apis/route53/src/main/java/org/jclouds/route53/features/HostedZoneApi.java +++ b/apis/route53/src/main/java/org/jclouds/route53/features/HostedZoneApi.java @@ -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 * @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("{name}{callerReference}") + @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("{name}{callerReference}{comment}") + @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 list(); /** * retrieves up to 100 zones in order. */ + @Named("ListHostedZones") + @GET + @Path("/hostedzone") + @XMLResponseParser(ListHostedZonesResponseHandler.class) IterableWithMarker listFirstPage(); /** * retrieves up to 100 zones in order, starting at {@code nextMarker} */ - IterableWithMarker listAt(String nextMarker); + @Named("ListHostedZones") + @GET + @Path("/hostedzone") + @XMLResponseParser(ListHostedZonesResponseHandler.class) + IterableWithMarker 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); } diff --git a/apis/route53/src/main/java/org/jclouds/route53/features/HostedZoneAsyncApi.java b/apis/route53/src/main/java/org/jclouds/route53/features/HostedZoneAsyncApi.java deleted file mode 100644 index 490a79c4bc..0000000000 --- a/apis/route53/src/main/java/org/jclouds/route53/features/HostedZoneAsyncApi.java +++ /dev/null @@ -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 - * @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("{name}{callerReference}") - @XMLResponseParser(CreateHostedZoneResponseHandler.class) - ListenableFuture createWithReference(@PayloadParam("name") String name, - @PayloadParam("callerReference") String callerReference); - - /** - * @see HostedZoneApi#createWithReferenceAndComment - */ - @Named("CreateHostedZone") - @POST - @Produces(APPLICATION_XML) - @Path("/hostedzone") - @Payload("{name}{callerReference}{comment}") - @XMLResponseParser(CreateHostedZoneResponseHandler.class) - ListenableFuture 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> list(); - - /** - * @see HostedZoneApi#listFirstPage - */ - @Named("ListHostedZones") - @GET - @Path("/hostedzone") - @XMLResponseParser(ListHostedZonesResponseHandler.class) - ListenableFuture> listFirstPage(); - - /** - * @see HostedZoneApi#listAt(String) - */ - @Named("ListHostedZones") - @GET - @Path("/hostedzone") - @XMLResponseParser(ListHostedZonesResponseHandler.class) - ListenableFuture> listAt(@QueryParam("marker") String nextMarker); - - /** - * @see HostedZoneApi#get() - */ - @Named("GetHostedZone") - @GET - @Path("/hostedzone/{zoneId}") - @XMLResponseParser(GetHostedZoneResponseHandler.class) - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture get(@PathParam("zoneId") String zoneId); - - /** - * @see HostedZoneApi#delete() - */ - @Named("DeleteHostedZone") - @DELETE - @Path("/hostedzone/{zoneId}") - @XMLResponseParser(ChangeHandler.class) - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture delete(@PathParam("zoneId") String zoneId); -} diff --git a/apis/route53/src/main/java/org/jclouds/route53/features/ResourceRecordSetApi.java b/apis/route53/src/main/java/org/jclouds/route53/features/ResourceRecordSetApi.java index 1eef42aa86..a3592e384d 100644 --- a/apis/route53/src/main/java/org/jclouds/route53/features/ResourceRecordSetApi.java +++ b/apis/route53/src/main/java/org/jclouds/route53/features/ResourceRecordSetApi.java @@ -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 * @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("CREATE{rrs}") + @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 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("DELETE{rrs}") + @XMLResponseParser(ChangeHandler.class) + @Fallback(NullOnNotFoundOr404.class) @Nullable - Change delete(ResourceRecordSet rrs); + Change delete(@PayloadParam("rrs") @ParamParser(SerializeRRS.class) ResourceRecordSet rrs); } diff --git a/apis/route53/src/main/java/org/jclouds/route53/features/ResourceRecordSetAsyncApi.java b/apis/route53/src/main/java/org/jclouds/route53/features/ResourceRecordSetAsyncApi.java deleted file mode 100644 index f008ae4d16..0000000000 --- a/apis/route53/src/main/java/org/jclouds/route53/features/ResourceRecordSetAsyncApi.java +++ /dev/null @@ -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 - * @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("CREATE{rrs}") - @XMLResponseParser(ChangeHandler.class) - ListenableFuture create(@PayloadParam("rrs") @ParamParser(SerializeRRS.class) ResourceRecordSet rrs); - - /** - * @see ResourceRecordSetApi#apply - */ - @Named("ChangeResourceRecordSets") - @POST - @Produces(APPLICATION_XML) - @Path("/rrset") - @XMLResponseParser(ChangeHandler.class) - ListenableFuture apply(@BinderParam(BindChangeBatch.class) ChangeBatch changes); - - /** - * @see ResourceRecordSetApi#list() - */ - @Named("ListResourceRecordSets") - @GET - @Path("/rrset") - @XMLResponseParser(ListResourceRecordSetsResponseHandler.class) - @Transform(ResourceRecordSetIterableToPagedIterable.class) - ListenableFuture> list(); - - /** - * @see ResourceRecordSetApi#listFirstPage - */ - @Named("ListResourceRecordSets") - @GET - @Path("/rrset") - @XMLResponseParser(ListResourceRecordSetsResponseHandler.class) - ListenableFuture listFirstPage(); - - /** - * @see ResourceRecordSetApi#listAt(NextRecord) - */ - @Named("ListResourceRecordSets") - @GET - @Path("/rrset") - @XMLResponseParser(ListResourceRecordSetsResponseHandler.class) - ListenableFuture listAt(@BinderParam(BindNextRecord.class) NextRecord nextRecord); - - /** - * @see ResourceRecordSetApi#delete - */ - @Named("ChangeResourceRecordSets") - @POST - @Produces(APPLICATION_XML) - @Path("/rrset") - @Payload("DELETE{rrs}") - @XMLResponseParser(ChangeHandler.class) - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture delete(@PayloadParam("rrs") @ParamParser(SerializeRRS.class) ResourceRecordSet rrs); -} diff --git a/apis/route53/src/test/java/org/jclouds/route53/Route53ApiMetadataTest.java b/apis/route53/src/test/java/org/jclouds/route53/Route53ApiMetadataTest.java index 76ef1b3f53..13094b58f4 100644 --- a/apis/route53/src/test/java/org/jclouds/route53/Route53ApiMetadataTest.java +++ b/apis/route53/src/test/java/org/jclouds/route53/Route53ApiMetadataTest.java @@ -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.> of()); } diff --git a/apis/route53/src/test/java/org/jclouds/route53/internal/BaseRoute53ApiLiveTest.java b/apis/route53/src/test/java/org/jclouds/route53/internal/BaseRoute53ApiLiveTest.java index d26a64ae3d..d8684b4388 100644 --- a/apis/route53/src/test/java/org/jclouds/route53/internal/BaseRoute53ApiLiveTest.java +++ b/apis/route53/src/test/java/org/jclouds/route53/internal/BaseRoute53ApiLiveTest.java @@ -49,7 +49,8 @@ public class BaseRoute53ApiLiveTest extends BaseApiLiveTest { super.setup(); inSync = retry(new Predicate() { 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); } diff --git a/apis/route53/src/test/java/org/jclouds/route53/internal/BaseRoute53ExpectTest.java b/apis/route53/src/test/java/org/jclouds/route53/internal/BaseRoute53ExpectTest.java index 78f6f066ee..44886e79d8 100644 --- a/apis/route53/src/test/java/org/jclouds/route53/internal/BaseRoute53ExpectTest.java +++ b/apis/route53/src/test/java/org/jclouds/route53/internal/BaseRoute53ExpectTest.java @@ -22,9 +22,9 @@ import static javax.ws.rs.core.Response.Status.NOT_FOUND; 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; /** @@ -37,8 +37,8 @@ public class BaseRoute53ExpectTest extends BaseRestApiExpectTest { 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) { @@ -51,6 +51,6 @@ public class BaseRoute53ExpectTest extends BaseRestApiExpectTest { @Override protected Module createModule() { - return new TestRoute53RestClientModule(); + return new TestRoute53HttpApiModule(); } } diff --git a/apis/sts/src/main/java/org/jclouds/aws/config/AWSHttpApiModule.java b/apis/sts/src/main/java/org/jclouds/aws/config/AWSHttpApiModule.java new file mode 100644 index 0000000000..0b0437f096 --- /dev/null +++ b/apis/sts/src/main/java/org/jclouds/aws/config/AWSHttpApiModule.java @@ -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 extends HttpApiModule { + protected AWSHttpApiModule() { + + } + + protected AWSHttpApiModule(Class api) { + super(api); + } + + @Provides + @ClientError + @Singleton + protected Set 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); + } + +} diff --git a/apis/sts/src/main/java/org/jclouds/aws/config/AWSRestClientModule.java b/apis/sts/src/main/java/org/jclouds/aws/config/AWSRestClientModule.java index f953f15a23..2638605c5b 100644 --- a/apis/sts/src/main/java/org/jclouds/aws/config/AWSRestClientModule.java +++ b/apis/sts/src/main/java/org/jclouds/aws/config/AWSRestClientModule.java @@ -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 extends RestClientModule { diff --git a/apis/sts/src/main/java/org/jclouds/aws/config/FormSigningHttpApiModule.java b/apis/sts/src/main/java/org/jclouds/aws/config/FormSigningHttpApiModule.java new file mode 100644 index 0000000000..bb677cd5c6 --- /dev/null +++ b/apis/sts/src/main/java/org/jclouds/aws/config/FormSigningHttpApiModule.java @@ -0,0 +1,61 @@ +/** + * 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; + +/** + * Configures signature process and dependencies needed for AWS Query apis + * (which we sent as POST requests, hence the name Form). + * + * @author Adrian Cole + */ +@ConfiguresHttpApi +public abstract class FormSigningHttpApiModule extends AWSHttpApiModule { + protected FormSigningHttpApiModule() { + + } + + protected FormSigningHttpApiModule(Class 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; + } + +} diff --git a/apis/sts/src/main/java/org/jclouds/aws/xml/SessionCredentialsHandler.java b/apis/sts/src/main/java/org/jclouds/aws/xml/SessionCredentialsHandler.java index c26f78ab4e..7e010a48ea 100644 --- a/apis/sts/src/main/java/org/jclouds/aws/xml/SessionCredentialsHandler.java +++ b/apis/sts/src/main/java/org/jclouds/aws/xml/SessionCredentialsHandler.java @@ -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 * - * @see STSAsyncApi * @see * @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); } diff --git a/apis/sts/src/main/java/org/jclouds/sts/STSApiMetadata.java b/apis/sts/src/main/java/org/jclouds/sts/STSApiMetadata.java index 9fc653a480..e5e31f960b 100644 --- a/apis/sts/src/main/java/org/jclouds/sts/STSApiMetadata.java +++ b/apis/sts/src/main/java/org/jclouds/sts/STSApiMetadata.java @@ -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> CONTEXT_TOKEN = new TypeToken>() { - private static final long serialVersionUID = 1L; - }; +public class STSApiMetadata extends BaseHttpApiMetadata { @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 { + public static class Builder extends BaseHttpApiMetadata.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 diff --git a/apis/sts/src/main/java/org/jclouds/sts/STSAsyncApi.java b/apis/sts/src/main/java/org/jclouds/sts/STSAsyncApi.java deleted file mode 100644 index fdeed7519e..0000000000 --- a/apis/sts/src/main/java/org/jclouds/sts/STSAsyncApi.java +++ /dev/null @@ -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 - *

    - * - * @see - * @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 createTemporaryCredentials(); - - /** - * @see STSApi#createTemporaryCredentials(SessionCredentialsOptions) - */ - @Named("GetSessionToken") - @POST - @Path("/") - @XMLResponseParser(SessionCredentialsHandler.class) - @FormParams(keys = "Action", values = "GetSessionToken") - ListenableFuture createTemporaryCredentials(SessionCredentialsOptions options); - - /** - * @see STSApi#assumeRole(String, String) - */ - @Named("AssumeRole") - @POST - @Path("/") - @XMLResponseParser(UserAndSessionCredentialsHandler.class) - @FormParams(keys = "Action", values = "AssumeRole") - ListenableFuture 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 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 createFederatedUser(@FormParam("Name") String userName); - - /** - * @see STSApi#createFederatedUser(FederatedUserOptions) - */ - @Named("GetFederationToken") - @POST - @Path("/") - @XMLResponseParser(UserAndSessionCredentialsHandler.class) - @FormParams(keys = "Action", values = "GetFederationToken") - ListenableFuture createFederatedUser(@FormParam("Name") String userName, FederatedUserOptions options); -} diff --git a/apis/sts/src/main/java/org/jclouds/sts/config/STSRestClientModule.java b/apis/sts/src/main/java/org/jclouds/sts/config/STSHttpApiModule.java similarity index 68% rename from apis/sts/src/main/java/org/jclouds/sts/config/STSRestClientModule.java rename to apis/sts/src/main/java/org/jclouds/sts/config/STSHttpApiModule.java index b912dbd8da..7ec9db4a02 100644 --- a/apis/sts/src/main/java/org/jclouds/sts/config/STSRestClientModule.java +++ b/apis/sts/src/main/java/org/jclouds/sts/config/STSHttpApiModule.java @@ -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 { - - public STSRestClientModule() { - super(typeToken(STSApi.class), typeToken(STSAsyncApi.class)); - } +@ConfiguresHttpApi +public class STSHttpApiModule extends FormSigningHttpApiModule { } diff --git a/apis/sts/src/test/java/org/jclouds/sts/STSApiMetadataTest.java b/apis/sts/src/test/java/org/jclouds/sts/STSApiMetadataTest.java index 98c5431b44..cd9c5ff671 100644 --- a/apis/sts/src/test/java/org/jclouds/sts/STSApiMetadataTest.java +++ b/apis/sts/src/test/java/org/jclouds/sts/STSApiMetadataTest.java @@ -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.> of()); } diff --git a/apis/sts/src/test/java/org/jclouds/sts/internal/BaseSTSExpectTest.java b/apis/sts/src/test/java/org/jclouds/sts/internal/BaseSTSExpectTest.java index b4004180e1..288d4cbb37 100644 --- a/apis/sts/src/test/java/org/jclouds/sts/internal/BaseSTSExpectTest.java +++ b/apis/sts/src/test/java/org/jclouds/sts/internal/BaseSTSExpectTest.java @@ -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 extends BaseRestApiExpectTest { 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 extends BaseRestApiExpectTest { @Override protected Module createModule() { - return new TestSTSRestClientModule(); + return new TestSTSHttpApiModule(); } } diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftKeystoneApiMetadata.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftKeystoneApiMetadata.java index f547168a16..8c556575cb 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftKeystoneApiMetadata.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftKeystoneApiMetadata.java @@ -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.>builder() + .add(MappedAuthenticationApiModule.class) .add(KeystoneStorageEndpointModule.class) .add(KeystoneAuthenticationModule.RegionModule.class) .add(SwiftKeystoneRestClientModule.class) diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/config/TemporaryUrlExtensionModule.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/config/TemporaryUrlExtensionModule.java index bcc6882ed5..1da670c9cc 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/config/TemporaryUrlExtensionModule.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/config/TemporaryUrlExtensionModule.java @@ -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.bindSyncToAsyncHttpApi; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; import java.util.concurrent.TimeUnit; @@ -70,7 +70,7 @@ public abstract class TemporaryUrlExtensionModule { protected void bindTemporaryUrlKeyApi() { - bindHttpApi(binder(), TemporaryUrlKeyApi.class, KeystoneTemporaryUrlKeyAsyncApi.class); + bindSyncToAsyncHttpApi(binder(), TemporaryUrlKeyApi.class, KeystoneTemporaryUrlKeyAsyncApi.class); } @Override @@ -115,7 +115,7 @@ public abstract class TemporaryUrlExtensionModule>builder() + .add(MappedAuthenticationApiModule.class) .add(KeystoneStorageEndpointModule.class) .add(KeystoneAuthenticationModule.RegionModule.class) .add(SwiftKeystoneRestClientModule.class) diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/config/VCloudRestClientModule.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/config/VCloudRestClientModule.java index 6026cab53e..8be7904ca9 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/config/VCloudRestClientModule.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/config/VCloudRestClientModule.java @@ -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.bindSyncToAsyncHttpApi; 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>() { }).to(new TypeLiteral() { }); - bindHttpApi(binder(), VCloudVersionsClient.class, VCloudVersionsAsyncClient.class); - bindHttpApi(binder(), VCloudLoginClient.class, VCloudLoginAsyncClient.class); + bindSyncToAsyncHttpApi(binder(), VCloudVersionsClient.class, VCloudVersionsAsyncClient.class); + bindSyncToAsyncHttpApi(binder(), VCloudLoginClient.class, VCloudLoginAsyncClient.class); } protected void bindCacheLoaders() { diff --git a/blobstore/src/main/java/org/jclouds/blobstore/config/TransientBlobStoreContextModule.java b/blobstore/src/main/java/org/jclouds/blobstore/config/TransientBlobStoreContextModule.java index e04e90ceec..004b00d4c5 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/config/TransientBlobStoreContextModule.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/config/TransientBlobStoreContextModule.java @@ -18,7 +18,7 @@ */ package org.jclouds.blobstore.config; -import static org.jclouds.rest.config.BinderUtils.bindBlockingApi; +import static org.jclouds.rest.config.BinderUtils.bindSyncToAsyncApi; 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); + bindSyncToAsyncApi(binder(), LocalBlobStore.class, AsyncBlobStore.class); install(new BlobStoreObjectModule()); install(new BlobStoreMapModule()); bind(BlobStore.class).to(LocalBlobStore.class); diff --git a/common/openstack/src/main/java/org/jclouds/openstack/config/OpenStackAuthenticationModule.java b/common/openstack/src/main/java/org/jclouds/openstack/config/OpenStackAuthenticationModule.java index 6fdacfd6a7..c71469529b 100644 --- a/common/openstack/src/main/java/org/jclouds/openstack/config/OpenStackAuthenticationModule.java +++ b/common/openstack/src/main/java/org/jclouds/openstack/config/OpenStackAuthenticationModule.java @@ -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.bindSyncToAsyncHttpApi; 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); + bindSyncToAsyncHttpApi(binder(), OpenStackAuthClient.class, OpenStackAuthAsyncClient.class); install(new FactoryModuleBuilder().build(URIFromAuthenticationResponseForService.Factory.class)); bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class); } diff --git a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v1_1/config/AuthenticationServiceModule.java b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v1_1/config/AuthenticationServiceModule.java index a7fabd78c2..285513d48e 100644 --- a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v1_1/config/AuthenticationServiceModule.java +++ b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v1_1/config/AuthenticationServiceModule.java @@ -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.bindSyncToAsyncHttpApi; 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); + bindSyncToAsyncHttpApi(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) diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/TerremarkVCloudRestClientModule.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/TerremarkVCloudRestClientModule.java index 2042f71231..8227459094 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/TerremarkVCloudRestClientModule.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/config/TerremarkVCloudRestClientModule.java @@ -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.bindSyncToAsyncHttpApi; 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 extends RestClientModule>>() { }).to(new TypeLiteral() { }); - bindHttpApi(binder(), TerremarkVCloudVersionsClient.class, TerremarkVCloudVersionsAsyncClient.class); - bindHttpApi(binder(), TerremarkVCloudLoginClient.class, TerremarkVCloudLoginAsyncClient.class); + bindSyncToAsyncHttpApi(binder(), TerremarkVCloudVersionsClient.class, TerremarkVCloudVersionsAsyncClient.class); + bindSyncToAsyncHttpApi(binder(), TerremarkVCloudLoginClient.class, TerremarkVCloudLoginAsyncClient.class); } @Provides diff --git a/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java b/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java index 9e1f00b977..1f6b9661ac 100644 --- a/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java +++ b/compute/src/main/java/org/jclouds/compute/internal/UtilsImpl.java @@ -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 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 credentialStore, LoggerFactory loggerFactory, - Function 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 credentialStore, LoggerFactory loggerFactory, + Function sshForNode) { super(injector, json, xml, simpleClient, simpleAsyncClient, encryption, date, userExecutor, ioExecutor, eventBus, credentialStore, loggerFactory); this.sshForNode = sshForNode; diff --git a/core/src/main/java/org/jclouds/ContextBuilder.java b/core/src/main/java/org/jclouds/ContextBuilder.java index ccdf4eb296..6bd2679a29 100644 --- a/core/src/main/java/org/jclouds/ContextBuilder.java +++ b/core/src/main/java/org/jclouds/ContextBuilder.java @@ -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.SyncToAsyncHttpInvocationModule; 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 creds, List inputModules) { List modules = newArrayList(); modules.addAll(inputModules); - boolean restModuleSpecifiedByUser = restClientModulePresent(inputModules); - Iterable defaultModules = ifSpecifiedByUserDontIncludeDefaultRestModule( - providerMetadata.getApiMetadata(), restModuleSpecifiedByUser); + boolean apiModuleSpecifiedByUser = apiModulePresent(inputModules); + Iterable 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 modules) { - if (apiMetadata instanceof RestApiMetadata) { + if (apiMetadata instanceof HttpApiMetadata) { + try { + modules + .add(new BindApiContextWithWildcardExtendsExplicitAndRawType(HttpApiMetadata.class.cast(apiMetadata))); + } catch (IllegalArgumentException ignored) { + + } + } else if (apiMetadata instanceof RestApiMetadata) { try { modules.add(new BindRestContextWithWildcardExtendsExplicitAndRawType(RestApiMetadata.class - .cast(apiMetadata))); - } catch (IllegalArgumentException e) { + .cast(apiMetadata))); + } catch (IllegalArgumentException ignored) { } } } - static Iterable ifSpecifiedByUserDontIncludeDefaultRestModule(ApiMetadata apiMetadata, + static Iterable ifSpecifiedByUserDontIncludeDefaultApiModule(ApiMetadata apiMetadata, boolean restModuleSpecifiedByUser) { Iterable defaultModules = transform(apiMetadata.getDefaultModules(), new Function, 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 modules) { - if (!restClientModulePresent(modules)) { + if (!apiModulePresent(modules)) { addClientModule(apiMetadata, modules); } } + private static boolean apiModulePresent(List modules) { + return any(modules, or(configuresApi, configuresRest)); + } - static Predicate configuresRest = new Predicate() { + private static Predicate configuresApi = new Predicate() { + public boolean apply(Module input) { + return input.getClass().isAnnotationPresent(ConfiguresHttpApi.class); + } + + }; + + private static Predicate configuresRest = new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(ConfiguresRestClient.class); } }; - static boolean restClientModulePresent(List modules) { - return any(modules, configuresRest); - } - @SuppressWarnings({ "unchecked", "rawtypes" }) static void addClientModule(ApiMetadata apiMetadata, List 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 SyncToAsyncHttpInvocationModule()); } } diff --git a/core/src/main/java/org/jclouds/config/BindApiContextWithWildcardExtendsExplicitAndRawType.java b/core/src/main/java/org/jclouds/config/BindApiContextWithWildcardExtendsExplicitAndRawType.java new file mode 100644 index 0000000000..b4f641c560 --- /dev/null +++ b/core/src/main/java/org/jclouds/config/BindApiContextWithWildcardExtendsExplicitAndRawType.java @@ -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}, 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())))); + } +} diff --git a/core/src/main/java/org/jclouds/config/BindRestContextWithWildcardExtendsExplicitAndRawType.java b/core/src/main/java/org/jclouds/config/BindRestContextWithWildcardExtendsExplicitAndRawType.java index d14c554b74..e47d718e74 100644 --- a/core/src/main/java/org/jclouds/config/BindRestContextWithWildcardExtendsExplicitAndRawType.java +++ b/core/src/main/java/org/jclouds/config/BindRestContextWithWildcardExtendsExplicitAndRawType.java @@ -35,7 +35,10 @@ import com.google.inject.util.Types; * Allows you to lookup the {@link RestApiMetadata#getContext()} as {@link RestContext}, {@code RestContext}, 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; diff --git a/core/src/main/java/org/jclouds/providers/AnonymousProviderMetadata.java b/core/src/main/java/org/jclouds/providers/AnonymousProviderMetadata.java index 5bbdeeedd7..ccede4c6d4 100644 --- a/core/src/main/java/org/jclouds/providers/AnonymousProviderMetadata.java +++ b/core/src/main/java/org/jclouds/providers/AnonymousProviderMetadata.java @@ -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 ProviderMetadata forApiOnEndpoint(Class 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()); diff --git a/core/src/main/java/org/jclouds/reflect/Types2.java b/core/src/main/java/org/jclouds/reflect/Types2.java new file mode 100644 index 0000000000..c900d3dee7 --- /dev/null +++ b/core/src/main/java/org/jclouds/reflect/Types2.java @@ -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 TypeToken checkBound(TypeToken type) throws IllegalStateException { + checkState(!(type.getType() instanceof TypeVariable), + "unbound type variable: %s, use ctor that explicitly assigns this", type); + return type; + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/AnonymousHttpApiMetadata.java b/core/src/main/java/org/jclouds/rest/AnonymousHttpApiMetadata.java new file mode 100644 index 0000000000..b5335ca0f0 --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/AnonymousHttpApiMetadata.java @@ -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 extends BaseHttpApiMetadata { + + public static AnonymousHttpApiMetadata forApi(Class httpApi) { + return new Builder(httpApi).build(); + } + + @Override + public Builder toBuilder() { + return new Builder(getApi()).fromApiMetadata(this); + } + + private AnonymousHttpApiMetadata(Builder builder) { + super(builder); + } + + private static final class Builder extends BaseHttpApiMetadata.Builder> { + + private Builder(Class api) { + super(api); + id(api.getSimpleName()) + .identityName("unused") + .defaultIdentity("foo") + .version("1") + .documentation(URI.create("http://jclouds.org/documentation")); + } + + @Override + public AnonymousHttpApiMetadata build() { + return new AnonymousHttpApiMetadata(this); + } + + @Override + protected Builder self() { + return this; + } + } +} diff --git a/core/src/main/java/org/jclouds/rest/AnonymousRestApiMetadata.java b/core/src/main/java/org/jclouds/rest/AnonymousRestApiMetadata.java index 8eecd360de..b5d10b41b8 100644 --- a/core/src/main/java/org/jclouds/rest/AnonymousRestApiMetadata.java +++ b/core/src/main/java/org/jclouds/rest/AnonymousRestApiMetadata.java @@ -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 { diff --git a/core/src/main/java/org/jclouds/rest/ApiContext.java b/core/src/main/java/org/jclouds/rest/ApiContext.java new file mode 100644 index 0000000000..8aac086d86 --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/ApiContext.java @@ -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. + * + *

    Note

    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 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(); +} diff --git a/core/src/main/java/org/jclouds/rest/ConfiguresRestContext.java b/core/src/main/java/org/jclouds/rest/ConfiguresHttpApi.java similarity index 89% rename from core/src/main/java/org/jclouds/rest/ConfiguresRestContext.java rename to core/src/main/java/org/jclouds/rest/ConfiguresHttpApi.java index 021bc4c38a..1d39d79eb4 100644 --- a/core/src/main/java/org/jclouds/rest/ConfiguresRestContext.java +++ b/core/src/main/java/org/jclouds/rest/ConfiguresHttpApi.java @@ -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 { } diff --git a/core/src/main/java/org/jclouds/rest/HttpApiMetadata.java b/core/src/main/java/org/jclouds/rest/HttpApiMetadata.java new file mode 100644 index 0000000000..69e31fa991 --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/HttpApiMetadata.java @@ -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 extends ApiMetadata { + + public static interface Builder> extends ApiMetadata.Builder { + + /** + * @see ApiMetadata#getApi() + */ + T api(Class api); + } + + /** + * + * @return the type of the java api which has http annotations on its methods. + */ + Class getApi(); +} diff --git a/core/src/main/java/org/jclouds/rest/HttpAsyncClient.java b/core/src/main/java/org/jclouds/rest/HttpAsyncClient.java index 49c3326ef7..7cce631728 100644 --- a/core/src/main/java/org/jclouds/rest/HttpAsyncClient.java +++ b/core/src/main/java/org/jclouds/rest/HttpAsyncClient.java @@ -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#post diff --git a/core/src/main/java/org/jclouds/rest/HttpClient.java b/core/src/main/java/org/jclouds/rest/HttpClient.java index ab9eca183f..7e6a720abb 100644 --- a/core/src/main/java/org/jclouds/rest/HttpClient.java +++ b/core/src/main/java/org/jclouds/rest/HttpClient.java @@ -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); + } diff --git a/core/src/main/java/org/jclouds/rest/RestApiMetadata.java b/core/src/main/java/org/jclouds/rest/RestApiMetadata.java index 7798cd1af3..7acb0564ed 100644 --- a/core/src/main/java/org/jclouds/rest/RestApiMetadata.java +++ b/core/src/main/java/org/jclouds/rest/RestApiMetadata.java @@ -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 { diff --git a/core/src/main/java/org/jclouds/rest/Utils.java b/core/src/main/java/org/jclouds/rest/Utils.java index c5bf450324..44695acdcf 100644 --- a/core/src/main/java/org/jclouds/rest/Utils.java +++ b/core/src/main/java/org/jclouds/rest/Utils.java @@ -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(); diff --git a/core/src/main/java/org/jclouds/rest/config/AsyncHttpApiProvider.java b/core/src/main/java/org/jclouds/rest/config/AnnotatedHttpApiProvider.java similarity index 74% rename from core/src/main/java/org/jclouds/rest/config/AsyncHttpApiProvider.java rename to core/src/main/java/org/jclouds/rest/config/AnnotatedHttpApiProvider.java index 2765f27349..40ec61cdcd 100644 --- a/core/src/main/java/org/jclouds/rest/config/AsyncHttpApiProvider.java +++ b/core/src/main/java/org/jclouds/rest/config/AnnotatedHttpApiProvider.java @@ -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 implements Provider { - private final Class asyncApiType; +public class AnnotatedHttpApiProvider implements Provider { + private final Class annotatedApiType; private final DelegatesToInvocationFunction> httpInvoker; @Inject - private AsyncHttpApiProvider(DelegatesToInvocationFunction> httpInvoker, - TypeLiteral asyncApiType) { + private AnnotatedHttpApiProvider(DelegatesToInvocationFunction> httpInvoker, + Class 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); } } diff --git a/core/src/main/java/org/jclouds/rest/config/AnnotatedSyncToAsyncHttpApiProvider.java b/core/src/main/java/org/jclouds/rest/config/AnnotatedSyncToAsyncHttpApiProvider.java new file mode 100644 index 0000000000..0dfb6f6f3a --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/config/AnnotatedSyncToAsyncHttpApiProvider.java @@ -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.DelegatesToPotentiallySyncToAsyncInvocationFunction; + +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 AnnotatedSyncToAsyncHttpApiProvider implements Provider { + private final Class annotatedApiType; + private final DelegatesToPotentiallySyncToAsyncInvocationFunction> httpInvoker; + + @Inject + private AnnotatedSyncToAsyncHttpApiProvider( + DelegatesToPotentiallySyncToAsyncInvocationFunction> httpInvoker, + TypeLiteral annotatedApiType) { + this.httpInvoker = httpInvoker; + this.annotatedApiType = annotatedApiType.getRawType(); + } + + @SuppressWarnings("unchecked") + @Override + public A get() { + return (A) Proxy.newProxyInstance(annotatedApiType.getClassLoader(), new Class[] { annotatedApiType }, + httpInvoker); + } +} diff --git a/core/src/main/java/org/jclouds/rest/config/BinderUtils.java b/core/src/main/java/org/jclouds/rest/config/BinderUtils.java index 4cf560c9f9..7ef6f6d63a 100644 --- a/core/src/main/java/org/jclouds/rest/config/BinderUtils.java +++ b/core/src/main/java/org/jclouds/rest/config/BinderUtils.java @@ -31,7 +31,32 @@ 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 + * sync interface that blocks + * @param + * api type with http annotations + * @param binder + * guice binder + * @param api + * type with http annotations + */ + public static void bindHttpApi(Binder binder, Class api) { + bindClass(binder, api); + bindAnnotatedHttpApiProvider(binder, api); + } + + @SuppressWarnings({ "unchecked", "serial" }) + private static void bindAnnotatedHttpApiProvider(Binder binder, Class annotated) { + TypeToken> token = new TypeToken>() { + }.where(new TypeParameter() { + }, 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 @@ -44,66 +69,89 @@ 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 void bindHttpApi(Binder binder, Class sync, Class async) { + @Deprecated + public static void bindSyncToAsyncHttpApi(Binder binder, Class sync, Class async) { bindClass(binder, sync); bindClass(binder, async); - bindAsyncHttpApiProvider(binder, async); + bindAnnotatedSyncToAsyncHttpApiProvider(binder, async); bindHttpApiProvider(binder, sync, async); } - - @SuppressWarnings("unchecked") - private static void bindAsyncHttpApiProvider(Binder binder, Class async) { - TypeToken> token = new TypeToken>() { - private static final long serialVersionUID = 1L; + + /** + * @deprecated will be removed in jclouds 1.7, as async interfaces are no + * longer supported. + */ + @Deprecated + @SuppressWarnings({ "unchecked", "serial" }) + private static void bindAnnotatedSyncToAsyncHttpApiProvider(Binder binder, Class annotated) { + TypeToken> token = new TypeToken>() { }.where(new TypeParameter() { - }, async); - binder.bind(async).toProvider(TypeLiteral.class.cast(TypeLiteral.get(token.getType()))); + }, annotated); + binder.bind(annotated).toProvider(TypeLiteral.class.cast(TypeLiteral.get(token.getType()))); } - - @SuppressWarnings("unchecked") + + /** + * + * @deprecated will be removed in jclouds 1.7, as async interfaces are no + * longer supported. + */ + @Deprecated + @SuppressWarnings({ "unchecked", "serial" }) private static void bindHttpApiProvider(Binder binder, Class sync, Class async) { - TypeToken> token = new TypeToken>() { - private static final long serialVersionUID = 1L; + TypeToken> token = new TypeToken>() { }.where(new TypeParameter() { }, sync).where(new TypeParameter() { }, 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 * sync interface that blocks * @param - * 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 void bindBlockingApi(Binder binder, Class sync, Class async) { + @Deprecated + public static void bindSyncToAsyncApi(Binder binder, Class sync, Class async) { bindClass(binder, sync); bindClass(binder, async); bindCallGetOnFutures(binder, sync, async); } - @SuppressWarnings("unchecked") + /** + * @deprecated will be removed in jclouds 1.7, as async interfaces are no + * longer supported. + */ + @Deprecated + @SuppressWarnings({ "unchecked", "serial" }) private static void bindCallGetOnFutures(Binder binder, Class sync, Class async) { TypeToken> token = new TypeToken>() { - private static final long serialVersionUID = 1L; }.where(new TypeParameter() { }, sync).where(new TypeParameter() { }, async); binder.bind(sync).toProvider(TypeLiteral.class.cast(TypeLiteral.get(token.getType()))); } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "serial" }) private static void bindClass(Binder binder, Class sync) { binder.bind(TypeLiteral.class.cast(TypeLiteral.get(new TypeToken>() { - private static final long serialVersionUID = 1L; }.where(new TypeParameter() { }, sync).getType()))).toInstance(sync); } diff --git a/core/src/main/java/org/jclouds/rest/config/CallGetOnFuturesProvider.java b/core/src/main/java/org/jclouds/rest/config/CallGetOnFuturesProvider.java index 27fb53c93d..5a297e3e3b 100644 --- a/core/src/main/java/org/jclouds/rest/config/CallGetOnFuturesProvider.java +++ b/core/src/main/java/org/jclouds/rest/config/CallGetOnFuturesProvider.java @@ -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.DelegatesToPotentiallySyncToAsyncInvocationFunction; 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 implements Provider { private final Class apiType; - private final DelegatesToInvocationFunction> syncInvoker; + private final DelegatesToPotentiallySyncToAsyncInvocationFunction> syncInvoker; @Inject private CallGetOnFuturesProvider(Cache, Invokable> invokables, - DelegatesToInvocationFunction> syncInvoker, Class apiType, + DelegatesToPotentiallySyncToAsyncInvocationFunction> syncInvoker, Class apiType, Class asyncApiType) { this.syncInvoker = syncInvoker; this.apiType = apiType; - RestModule.putInvokables(apiType, asyncApiType, invokables); + SyncToAsyncHttpInvocationModule.putInvokables(apiType, asyncApiType, invokables); } @SuppressWarnings("unchecked") diff --git a/core/src/main/java/org/jclouds/rest/config/HttpApiModule.java b/core/src/main/java/org/jclouds/rest/config/HttpApiModule.java new file mode 100644 index 0000000000..5c0e70b044 --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/config/HttpApiModule.java @@ -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 extends RestModule { + protected final Class 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(getClass()) { + private static final long serialVersionUID = 1L; + }).getRawType()); + } + + public HttpApiModule(Class api) { + this.api = api; + } + + @Override + protected void configure() { + super.configure(); + bind(new TypeLiteral>() { + }).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. + * + *
    +    * bind(HttpRetryHandler.class).annotatedWith(Redirection.class).to(AWSRedirectionRetryHandler.class);
    +    * bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(AWSClientErrorRetryHandler.class);
    +    * 
    + * + */ + protected void bindRetryHandlers() { + } + + /** + * overrides this to change the default error handlers for the http engine + * + * ex. + * + *
    +    * 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);
    +    * 
    + * + * + */ + protected void bindErrorHandlers() { + + } + +} diff --git a/core/src/main/java/org/jclouds/rest/config/RestClientModule.java b/core/src/main/java/org/jclouds/rest/config/RestClientModule.java index dfa63c1770..271547d056 100644 --- a/core/src/main/java/org/jclouds/rest/config/RestClientModule.java +++ b/core/src/main/java/org/jclouds/rest/config/RestClientModule.java @@ -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.bindSyncToAsyncHttpApi; -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 extends RestModule { protected final TypeToken syncClientType; protected final TypeToken
    asyncClientType; + private final SyncToAsyncHttpInvocationModule 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> sync2Async) { - super(sync2Async); + this.invocationModule = new SyncToAsyncHttpInvocationModule(sync2Async); this.syncClientType = checkBound(new TypeToken(getClass()) { private static final long serialVersionUID = 1L; }); @@ -51,15 +55,6 @@ public class RestClientModule extends RestModule { private static final long serialVersionUID = 1L; }); } - - /** - * @throws IllegalStateException if the type is an instanceof {@link TypeVariable} - */ - private static TypeToken checkBound(TypeToken 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 extends RestModule { * only necessary when type params are not resolvable at runtime. */ public RestClientModule(TypeToken syncClientType, TypeToken asyncClientType, Map, Class> sync2Async) { - super(sync2Async); + this.invocationModule = new SyncToAsyncHttpInvocationModule(sync2Async); this.syncClientType = checkBound(syncClientType); this.asyncClientType = checkBound(asyncClientType); } @@ -87,7 +82,8 @@ public class RestClientModule extends RestModule { @Override protected void configure() { super.configure(); - bindHttpApi(binder(), syncClientType.getRawType(), asyncClientType.getRawType()); + install(invocationModule); + bindSyncToAsyncHttpApi(binder(), syncClientType.getRawType(), asyncClientType.getRawType()); bindErrorHandlers(); bindRetryHandlers(); } diff --git a/core/src/main/java/org/jclouds/rest/config/RestModule.java b/core/src/main/java/org/jclouds/rest/config/RestModule.java index db7f67b07a..fb16e178ec 100644 --- a/core/src/main/java/org/jclouds/rest/config/RestModule.java +++ b/core/src/main/java/org/jclouds/rest/config/RestModule.java @@ -18,23 +18,13 @@ */ 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 com.google.common.util.concurrent.Atomics.newReference; -import static org.jclouds.reflect.Reflection2.method; -import static org.jclouds.reflect.Reflection2.methods; -import static org.jclouds.rest.config.BinderUtils.bindHttpApi; -import java.io.Closeable; import java.net.Proxy; import java.net.URI; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; -import javax.inject.Singleton; - import org.jclouds.fallbacks.MapHttp4xxCodesToExceptions; import org.jclouds.functions.IdentityFunction; import org.jclouds.http.HttpRequest; @@ -46,24 +36,14 @@ import org.jclouds.location.config.LocationModule; import org.jclouds.proxy.ProxyForURI; import org.jclouds.reflect.Invocation; import org.jclouds.rest.AuthorizationException; -import org.jclouds.rest.HttpAsyncClient; -import org.jclouds.rest.HttpClient; import org.jclouds.rest.binders.BindToJsonPayloadWrappedWith; -import org.jclouds.rest.internal.InvokeHttpMethod; import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.TransformerForRequest; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Supplier; -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; import com.google.inject.assistedinject.FactoryModuleBuilder; @@ -72,109 +52,25 @@ public class RestModule extends AbstractModule { public static final TypeLiteral> URI_SUPPLIER_TYPE = new TypeLiteral>() { }; - protected final Map, Class> sync2Async; protected final AtomicReference authException = newReference(); - public RestModule() { - this(ImmutableMap., Class> of()); - } - - public RestModule(Map, Class> sync2Async) { - this.sync2Async = sync2Async; - } - - /** - * seeds well-known invokables. - */ - @Provides - @Singleton - protected Cache, Invokable> seedKnownSync2AsyncInvokables() { - return seedKnownSync2AsyncInvokables(sync2Async); - } - - /** - * function view of above - */ - @Provides - @Singleton - protected Function sync2async(final Cache, Invokable> cache) { - return new Function() { - 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> seedKnownSync2AsyncInvokables(Map, Class> sync2Async) { - Cache, Invokable> sync2AsyncBuilder = CacheBuilder.newBuilder().build(); - putInvokables(HttpClient.class, HttpAsyncClient.class, sync2AsyncBuilder); - for (Map.Entry, 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> 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. - * - *

    note

    - * - * 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>() { - public Class apply(Parameter input) { - return input.getType().getRawType(); - } - }), Class.class); - } - protected void installLocations() { install(new LocationModule()); } @Override protected void configure() { - bind(new TypeLiteral, Class>>() { - }).toInstance(sync2Async); install(new SaxParserModule()); install(new GsonModule()); install(new SetCaller.Module()); install(new FactoryModuleBuilder().build(BindToJsonPayloadWrappedWith.Factory.class)); bind(new TypeLiteral>>() { }).to(TransformerForRequest.class); - bind(new TypeLiteral>() { - }).to(InvokeHttpMethod.class); bind(new TypeLiteral>() { }).to(MapHttp4xxCodesToExceptions.class); bind(new TypeLiteral>() { }).to(RestAnnotationProcessor.class); bind(IdentityFunction.class).toInstance(IdentityFunction.INSTANCE); - bindHttpApi(binder(), HttpClient.class, HttpAsyncClient.class); // this will help short circuit scenarios that can otherwise lock out users bind(new TypeLiteral>() { }).toInstance(authException); diff --git a/core/src/main/java/org/jclouds/rest/config/HttpApiProvider.java b/core/src/main/java/org/jclouds/rest/config/SyncToAsyncHttpApiProvider.java similarity index 68% rename from core/src/main/java/org/jclouds/rest/config/HttpApiProvider.java rename to core/src/main/java/org/jclouds/rest/config/SyncToAsyncHttpApiProvider.java index 4df9f77e63..57b80aadae 100644 --- a/core/src/main/java/org/jclouds/rest/config/HttpApiProvider.java +++ b/core/src/main/java/org/jclouds/rest/config/SyncToAsyncHttpApiProvider.java @@ -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.DelegatesToPotentiallySyncToAsyncInvocationFunction; 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 implements Provider { +public class SyncToAsyncHttpApiProvider implements Provider { private final Class apiType; - private final DelegatesToInvocationFunction> httpInvoker; + private final DelegatesToPotentiallySyncToAsyncInvocationFunction> httpInvoker; @Inject - private HttpApiProvider(Cache, Invokable> invokables, - DelegatesToInvocationFunction> httpInvoker, Class apiType, Class
    asyncApiType) { + private SyncToAsyncHttpApiProvider(Cache, Invokable> invokables, + DelegatesToPotentiallySyncToAsyncInvocationFunction> httpInvoker, Class apiType, Class asyncApiType) { this.httpInvoker = httpInvoker; this.apiType = apiType; - RestModule.putInvokables(apiType, asyncApiType, invokables); + SyncToAsyncHttpInvocationModule.putInvokables(apiType, asyncApiType, invokables); } @SuppressWarnings("unchecked") diff --git a/core/src/main/java/org/jclouds/rest/config/SyncToAsyncHttpInvocationModule.java b/core/src/main/java/org/jclouds/rest/config/SyncToAsyncHttpInvocationModule.java new file mode 100644 index 0000000000..81f85191a3 --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/config/SyncToAsyncHttpInvocationModule.java @@ -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.DelegatesToPotentiallySyncToAsyncInvocationFunction; +import org.jclouds.rest.internal.InvokeAndCallGetOnFutures; +import org.jclouds.rest.internal.InvokeSyncToAsyncHttpMethod; + +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 SyncToAsyncHttpInvocationModule extends AbstractModule { + protected final Map, Class> sync2Async; + + public SyncToAsyncHttpInvocationModule() { + this(ImmutableMap., Class> of()); + } + + public SyncToAsyncHttpInvocationModule(Map, Class> sync2Async) { + this.sync2Async = sync2Async; + } + + @Override + protected void configure() { + bind(new TypeLiteral, Class>>() { + }).toInstance(sync2Async); + bind(new TypeLiteral>() { + }).to(InvokeSyncToAsyncHttpMethod.class); + BinderUtils.bindSyncToAsyncHttpApi(binder(), HttpClient.class, HttpAsyncClient.class); + } + + /** + * seeds well-known invokables. + */ + @Provides + @Singleton + protected Cache, Invokable> seedKnownSync2AsyncInvokables() { + return seedKnownSync2AsyncInvokables(sync2Async); + } + + /** + * function view of above + * + * @see InvokeAndCallGetOnFutures + * @see InvokeSyncToAsyncHttpMethod + */ + @Provides + @Singleton + protected Function sync2async(final Cache, Invokable> cache) { + return new Function() { + 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> seedKnownSync2AsyncInvokables(Map, Class> sync2Async) { + Cache, Invokable> sync2AsyncBuilder = CacheBuilder.newBuilder().build(); + putInvokables(HttpClient.class, HttpAsyncClient.class, sync2AsyncBuilder); + for (Map.Entry, 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> 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. + * + *

    note

    + * + * 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>() { + public Class apply(Parameter input) { + return input.getType().getRawType(); + } + }), Class.class); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/internal/ApiContextImpl.java b/core/src/main/java/org/jclouds/rest/internal/ApiContextImpl.java new file mode 100644 index 0000000000..1296f43d7d --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/internal/ApiContextImpl.java @@ -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.internal; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Inject; + +import org.jclouds.annotations.Name; +import org.jclouds.domain.Credentials; +import org.jclouds.internal.ContextImpl; +import org.jclouds.lifecycle.Closer; +import org.jclouds.location.Provider; +import org.jclouds.providers.ProviderMetadata; +import org.jclouds.rest.ApiContext; +import org.jclouds.rest.Utils; + +import com.google.common.base.Supplier; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.Singleton; +import com.google.inject.TypeLiteral; + +/** + * @author Adrian Cole +*/ +@Singleton +public class ApiContextImpl
    extends ContextImpl implements ApiContext { + + private final A api; + + @Inject + protected ApiContextImpl(@Name String name, ProviderMetadata providerMetadata, + @Provider Supplier creds, Utils utils, Closer closer, Injector injector, TypeLiteral api) { + super(name, providerMetadata, creds, utils, closer); + checkNotNull(injector, "injector"); + this.api = injector.getInstance(Key.get(checkNotNull(api, "api"))); + } + + @Override + public A getApi() { + return api; + } +} diff --git a/core/src/main/java/org/jclouds/rest/internal/BaseHttpApiMetadata.java b/core/src/main/java/org/jclouds/rest/internal/BaseHttpApiMetadata.java new file mode 100644 index 0000000000..cbc0ef3021 --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/internal/BaseHttpApiMetadata.java @@ -0,0 +1,121 @@ +/** + * 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.internal; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.reflect.Reflection2.typeToken; +import static org.jclouds.reflect.Types2.checkBound; + +import java.util.Properties; + +import org.jclouds.apis.ApiMetadata; +import org.jclouds.apis.internal.BaseApiMetadata; +import org.jclouds.rest.ApiContext; +import org.jclouds.rest.HttpApiMetadata; + +import com.google.common.annotations.Beta; +import com.google.common.base.Objects.ToStringHelper; +import com.google.common.reflect.TypeParameter; +import com.google.common.reflect.TypeToken; + +/** + * Useful in creating http apis. + * + * @author Adrian Cole + */ +@Beta +public abstract class BaseHttpApiMetadata extends BaseApiMetadata implements HttpApiMetadata { + + protected final Class api; + + protected BaseHttpApiMetadata(Builder builder) { + super(builder); + this.api = checkNotNull(builder.api, "api"); + } + + public static Properties defaultProperties() { + Properties props = BaseApiMetadata.defaultProperties(); + return props; + } + + public static TypeToken> contextToken(TypeToken apiToken) { + return new TypeToken>() { + private static final long serialVersionUID = 1L; + }.where(new TypeParameter() { + }, apiToken); + } + + public static abstract class Builder> extends BaseApiMetadata.Builder implements + HttpApiMetadata.Builder { + protected Class 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 Builder() { + this.api = Class.class.cast(checkBound(new TypeToken(getClass()) { + private static final long serialVersionUID = 1L; + }).getRawType()); + init(); + } + + protected Builder(Class api) { + this.api = checkNotNull(api, "api"); + init(); + } + + private void init() { + api(api) + .name(api.getSimpleName()) + .context(contextToken(typeToken(api))) + .defaultProperties(BaseHttpApiMetadata.defaultProperties()); + } + + @Override + public T api(Class api) { + this.api = checkNotNull(api, "api"); + return self(); + } + + @SuppressWarnings("unchecked") + @Override + public T fromApiMetadata(ApiMetadata in) { + if (in instanceof HttpApiMetadata) { + HttpApiMetadata http = HttpApiMetadata.class.cast(in); + api(Class.class.cast(http.getApi())); + } + super.fromApiMetadata(in); + return self(); + } + + } + + @Override + public Class getApi() { + return api; + } + + @Override + protected ToStringHelper string() { + return super.string().add("api", getApi()); + } +} diff --git a/core/src/main/java/org/jclouds/rest/internal/BaseRestApiMetadata.java b/core/src/main/java/org/jclouds/rest/internal/BaseRestApiMetadata.java index 4c4c8990b0..c10efb5c3f 100644 --- a/core/src/main/java/org/jclouds/rest/internal/BaseRestApiMetadata.java +++ b/core/src/main/java/org/jclouds/rest/internal/BaseRestApiMetadata.java @@ -26,7 +26,6 @@ import java.util.Properties; import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.internal.BaseApiMetadata; import org.jclouds.rest.RestApiMetadata; -import org.jclouds.rest.RestContext; import com.google.common.annotations.Beta; import com.google.common.base.Objects.ToStringHelper; @@ -37,6 +36,8 @@ import com.google.common.reflect.TypeToken; * Useful in creating rest apis. * * @author Adrian Cole + * @deprecated please use {@link BaseHttpApiMetadata} as + * async interface will be removed in jclouds 1.7. */ @Beta public abstract class BaseRestApiMetadata extends BaseApiMetadata implements RestApiMetadata { @@ -55,8 +56,8 @@ public abstract class BaseRestApiMetadata extends BaseApiMetadata implements Res return props; } - public static TypeToken> contextToken(TypeToken apiToken, TypeToken asyncApiToken) { - return new TypeToken>() { + public static TypeToken> contextToken(TypeToken apiToken, TypeToken asyncApiToken) { + return new TypeToken>() { private static final long serialVersionUID = 1L; }.where(new TypeParameter() { }, apiToken).where(new TypeParameter() { diff --git a/core/src/main/java/org/jclouds/rest/internal/DelegatesToInvocationFunction.java b/core/src/main/java/org/jclouds/rest/internal/DelegatesToInvocationFunction.java index 014b9116f5..f0a1055008 100644 --- a/core/src/main/java/org/jclouds/rest/internal/DelegatesToInvocationFunction.java +++ b/core/src/main/java/org/jclouds/rest/internal/DelegatesToInvocationFunction.java @@ -39,7 +39,6 @@ import java.lang.reflect.Type; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Map; import javax.inject.Inject; import javax.inject.Qualifier; @@ -78,7 +77,7 @@ import com.google.inject.util.Types; * The function that implements this dynamic proxy */ @Beta -public final class DelegatesToInvocationFunction> implements +public class DelegatesToInvocationFunction> implements InvocationHandler { private static final Object[] NO_ARGS = {}; @@ -161,20 +160,18 @@ public final class DelegatesToInvocationFunction ownerType; - private final SetCaller setCaller; - private final Map, Class> syncToAsync; - private final Function> optionalConverter; - private final F methodInvoker; + protected final Injector injector; + protected final TypeToken ownerType; + protected final SetCaller setCaller; + protected final Function> optionalConverter; + protected final F methodInvoker; @Inject - DelegatesToInvocationFunction(Injector injector, SetCaller setCaller, Map, Class> syncToAsync, + DelegatesToInvocationFunction(Injector injector, SetCaller setCaller, Class ownerType, Function> optionalConverter, F methodInvoker) { this.injector = checkNotNull(injector, "injector"); this.ownerType = typeToken(checkNotNull(ownerType, "ownerType")); this.setCaller = checkNotNull(setCaller, "setCaller"); - this.syncToAsync = checkNotNull(syncToAsync, "syncToAsync"); this.optionalConverter = checkNotNull(optionalConverter, "optionalConverter"); this.methodInvoker = checkNotNull(methodInvoker, "methodInvoker"); } @@ -200,20 +197,12 @@ public final class DelegatesToInvocationFunction methodInvokerFor(Class returnType) { + protected Key methodInvokerFor(Class returnType) { switch (methodInvoker.getClass().getTypeParameters().length) { case 0: return Key.get(methodInvoker.getClass()); case 1: return Key.get(Types.newParameterizedType(methodInvoker.getClass(), returnType)); - case 2: - if (syncToAsync.containsValue(returnType)) - return Key.get(Types.newParameterizedType(methodInvoker.getClass(), returnType, returnType)); - return Key.get(Types.newParameterizedType( - methodInvoker.getClass(), - returnType, - checkNotNull(syncToAsync.get(returnType), "need async type of %s for %s", returnType, - methodInvoker.getClass()))); } throw new IllegalArgumentException(returnType + " has too many type parameters"); } diff --git a/core/src/main/java/org/jclouds/rest/internal/DelegatesToPotentiallySyncToAsyncInvocationFunction.java b/core/src/main/java/org/jclouds/rest/internal/DelegatesToPotentiallySyncToAsyncInvocationFunction.java new file mode 100644 index 0000000000..f6843fb7c8 --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/internal/DelegatesToPotentiallySyncToAsyncInvocationFunction.java @@ -0,0 +1,74 @@ +/** + * 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.internal; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Map; + +import javax.inject.Inject; + +import org.jclouds.reflect.Invocation; +import org.jclouds.reflect.InvocationSuccess; +import org.jclouds.rest.config.SetCaller; + +import com.google.common.annotations.Beta; +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.util.Types; + +/** + * @param + * The enclosing type of the interface that a dynamic proxy like this + * implements + * @param + * The function that implements this dynamic proxy + * + * @deprecated please use {@link DelegatesToInvocationFunction} as + * async interface will be removed in jclouds 1.7. + */ +@Deprecated +@Beta +public final class DelegatesToPotentiallySyncToAsyncInvocationFunction> extends + DelegatesToInvocationFunction { + private final Map, Class> syncToAsync; + + @Inject + DelegatesToPotentiallySyncToAsyncInvocationFunction(Injector injector, SetCaller setCaller, Class ownerType, + Function> optionalConverter, F methodInvoker, + Map, Class> syncToAsync) { + super(injector, setCaller, ownerType, optionalConverter, methodInvoker); + this.syncToAsync = checkNotNull(syncToAsync, "syncToAsync"); + } + + protected Key methodInvokerFor(Class returnType) { + if (methodInvoker.getClass().getTypeParameters().length == 2) { + if (syncToAsync.containsValue(returnType)) + return Key.get(Types.newParameterizedType(methodInvoker.getClass(), returnType, returnType)); + return Key.get(Types.newParameterizedType( + methodInvoker.getClass(), + returnType, + checkNotNull(syncToAsync.get(returnType), "need async type of %s for %s", returnType, + methodInvoker.getClass()))); + } + return super.methodInvokerFor(returnType); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/internal/InvokeAndCallGetOnFutures.java b/core/src/main/java/org/jclouds/rest/internal/InvokeAndCallGetOnFutures.java index cda07b0003..a132b8aa40 100644 --- a/core/src/main/java/org/jclouds/rest/internal/InvokeAndCallGetOnFutures.java +++ b/core/src/main/java/org/jclouds/rest/internal/InvokeAndCallGetOnFutures.java @@ -37,7 +37,9 @@ import com.google.common.util.concurrent.ListenableFuture; /** * * @author Adrian Cole + * @deprecated will be removed in jclouds 1.7, as async interfaces are no longer supported. */ +@Deprecated public final class InvokeAndCallGetOnFutures implements Function { @Resource diff --git a/core/src/main/java/org/jclouds/rest/internal/InvokeHttpMethod.java b/core/src/main/java/org/jclouds/rest/internal/InvokeHttpMethod.java index e97a01a794..7a358ddc08 100644 --- a/core/src/main/java/org/jclouds/rest/internal/InvokeHttpMethod.java +++ b/core/src/main/java/org/jclouds/rest/internal/InvokeHttpMethod.java @@ -20,19 +20,14 @@ package org.jclouds.rest.internal; import static com.google.common.base.Objects.equal; import static com.google.common.base.Objects.toStringHelper; -import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Throwables.propagate; -import static com.google.common.util.concurrent.Futures.transform; -import static com.google.common.util.concurrent.Futures.withFallback; import static java.util.concurrent.TimeUnit.NANOSECONDS; -import static org.jclouds.Constants.PROPERTY_USER_THREADS; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; import javax.annotation.Resource; import javax.inject.Inject; -import javax.inject.Named; import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpCommandExecutorService; @@ -47,9 +42,6 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.base.Optional; -import com.google.common.reflect.Invokable; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.TimeLimiter; import com.google.common.util.concurrent.UncheckedTimeoutException; @@ -61,24 +53,19 @@ public class InvokeHttpMethod implements Function { @Resource private Logger logger = Logger.NULL; - private final Function sync2async; private final Function annotationProcessor; private final HttpCommandExecutorService http; - private final ListeningExecutorService userExecutor; private final TimeLimiter timeLimiter; private final Function> transformerForRequest; private final InvocationConfig config; @Inject @VisibleForTesting - InvokeHttpMethod(Function sync2async, Function annotationProcessor, + InvokeHttpMethod(Function annotationProcessor, HttpCommandExecutorService http, Function> transformerForRequest, - TimeLimiter timeLimiter, InvocationConfig config, - @Named(PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { - this.sync2async = sync2async; + TimeLimiter timeLimiter, InvocationConfig config) { this.annotationProcessor = annotationProcessor; this.http = http; - this.userExecutor = userExecutor; this.timeLimiter = timeLimiter; this.transformerForRequest = transformerForRequest; this.config = config; @@ -86,32 +73,11 @@ public class InvokeHttpMethod implements Function { @Override public Object apply(Invocation in) { - if (isFuture(in.getInvokable())) { - return submit(in); - } - Invocation async = toAsync(in); - Optional timeoutNanos = config.getTimeoutNanos(async); + Optional timeoutNanos = config.getTimeoutNanos(in); if (timeoutNanos.isPresent()) { - return invokeWithTimeout(async, timeoutNanos.get()); + return invokeWithTimeout(in, timeoutNanos.get()); } - return invoke(async); - } - - /** - * submits the {@linkplain HttpCommand} associated with {@code invocation}, - * {@link #getTransformer(String, HttpCommand) parses its response}, and - * applies a {@link #getFallback(String, Invocation, HttpCommand) fallback} - * if a {@code Throwable} is encountered. Parsing and Fallback occur on the - * {@code userExecutor} thread. - */ - public ListenableFuture submit(Invocation invocation) { - String commandName = config.getCommandName(invocation); - HttpCommand command = toCommand(commandName, invocation); - Function transformer = getTransformer(commandName, command); - org.jclouds.Fallback fallback = getFallback(commandName, invocation, command); - - logger.debug(">> submitting %s", commandName); - return withFallback(transform(http.submit(command), transformer, userExecutor), fallback); + return invoke(in); } /** @@ -224,17 +190,6 @@ public class InvokeHttpMethod implements Function { } } - /** - * looks up the corresponding {@code Invocation} that returns a - * {@code Future}. Only Invokables that return {@code Futures} are annotated - * in a way that can be parsed into an {@linkplain HttpRequest}. - */ - private Invocation toAsync(Invocation in) { - Invocation async = sync2async.apply(in); - checkState(isFuture(async.getInvokable()), "not a future: %s", async); - return async; - } - private HttpCommand toCommand(String commandName, Invocation invocation) { logger.trace(">> converting %s", commandName); HttpRequest request = annotationProcessor.apply(invocation); @@ -249,10 +204,6 @@ public class InvokeHttpMethod implements Function { return transformer; } - private boolean isFuture(Invokable in) { - return in.getReturnType().getRawType().equals(ListenableFuture.class); - } - @Override public boolean equals(Object o) { if (this == o) diff --git a/core/src/main/java/org/jclouds/rest/internal/InvokeSyncToAsyncHttpMethod.java b/core/src/main/java/org/jclouds/rest/internal/InvokeSyncToAsyncHttpMethod.java new file mode 100644 index 0000000000..c63f90a6dc --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/internal/InvokeSyncToAsyncHttpMethod.java @@ -0,0 +1,277 @@ +/** + * 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.internal; + +import static com.google.common.base.Objects.equal; +import static com.google.common.base.Objects.toStringHelper; +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Throwables.propagate; +import static com.google.common.util.concurrent.Futures.transform; +import static com.google.common.util.concurrent.Futures.withFallback; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static org.jclouds.Constants.PROPERTY_USER_THREADS; + +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; + +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpCommandExecutorService; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.logging.Logger; +import org.jclouds.reflect.Invocation; +import org.jclouds.rest.InvocationContext; +import org.jclouds.rest.config.InvocationConfig; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.base.Objects; +import com.google.common.base.Optional; +import com.google.common.reflect.Invokable; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.TimeLimiter; +import com.google.common.util.concurrent.UncheckedTimeoutException; + +/** + * @author Adrian Cole + * @deprecated will be replaced in jclouds 1.7 with {@link InvokeHttpMethod}, as async interfaces are no longer supported. + */ +@Deprecated +public class InvokeSyncToAsyncHttpMethod implements Function { + + @Resource + private Logger logger = Logger.NULL; + + private final Function sync2async; + private final Function annotationProcessor; + private final HttpCommandExecutorService http; + private final ListeningExecutorService userExecutor; + private final TimeLimiter timeLimiter; + private final Function> transformerForRequest; + private final InvocationConfig config; + + @Inject + @VisibleForTesting + InvokeSyncToAsyncHttpMethod(Function sync2async, Function annotationProcessor, + HttpCommandExecutorService http, Function> transformerForRequest, + TimeLimiter timeLimiter, InvocationConfig config, + @Named(PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) { + this.sync2async = sync2async; + this.annotationProcessor = annotationProcessor; + this.http = http; + this.userExecutor = userExecutor; + this.timeLimiter = timeLimiter; + this.transformerForRequest = transformerForRequest; + this.config = config; + } + + @Override + public Object apply(Invocation in) { + if (isFuture(in.getInvokable())) { + return submit(in); + } + Invocation async = toAsync(in); + Optional timeoutNanos = config.getTimeoutNanos(async); + if (timeoutNanos.isPresent()) { + return invokeWithTimeout(async, timeoutNanos.get()); + } + return invoke(async); + } + + /** + * submits the {@linkplain HttpCommand} associated with {@code invocation}, + * {@link #getTransformer(String, HttpCommand) parses its response}, and + * applies a {@link #getFallback(String, Invocation, HttpCommand) fallback} + * if a {@code Throwable} is encountered. Parsing and Fallback occur on the + * {@code userExecutor} thread. + */ + public ListenableFuture submit(Invocation invocation) { + String commandName = config.getCommandName(invocation); + HttpCommand command = toCommand(commandName, invocation); + Function transformer = getTransformer(commandName, command); + org.jclouds.Fallback fallback = getFallback(commandName, invocation, command); + + logger.debug(">> submitting %s", commandName); + return withFallback(transform(http.submit(command), transformer, userExecutor), fallback); + } + + /** + * invokes the {@linkplain HttpCommand} associated with {@code invocation}, + * {@link #getTransformer(String, HttpCommand) parses its response}, and + * applies a {@link #getFallback(String, Invocation, HttpCommand) fallback} + * if a {@code Throwable} is encountered. + */ + public Object invoke(Invocation invocation) { + String commandName = config.getCommandName(invocation); + HttpCommand command = toCommand(commandName, invocation); + Function transformer = getTransformer(commandName, command); + org.jclouds.Fallback fallback = getFallback(commandName, invocation, command); + + logger.debug(">> invoking %s", commandName); + try { + return transformer.apply(http.invoke(command)); + } catch (Throwable t) { + try { + return fallback.createOrPropagate(t); + } catch (Exception e) { + throw propagate(e); + } + } + } + + /** + * calls {@link #invoke(Invocation)}, timing out after the specified time + * limit. If the target method call finished before the limit is reached, the + * return value or exception is propagated to the caller exactly as-is. If, + * on the other hand, the time limit is reached, we attempt to abort the call + * to the target, and throw an {@link UncheckedTimeoutException} to the + * caller. + * + * @param invocation + * the Invocation to invoke via {@link #invoke(Invocation)} + * @param limitNanos + * with timeoutUnit, the maximum length of time to wait in + * nanoseconds + * @throws InterruptedException + * if our thread is interrupted during execution + * @throws UncheckedTimeoutException + * if the time limit is reached + * @see TimeLimiter#callWithTimeout(Callable, long, TimeUnit, boolean) + */ + public Object invokeWithTimeout(final Invocation invocation, final long limitNanos) { + String commandName = config.getCommandName(invocation); + HttpCommand command = toCommand(commandName, invocation); + org.jclouds.Fallback fallback = getFallback(commandName, invocation, command); + + logger.debug(">> blocking on %s for %s", invocation, limitNanos); + try { + return timeLimiter + .callWithTimeout(new InvokeAndTransform(commandName, command), limitNanos, NANOSECONDS, true); + } catch (Throwable t) { + try { + return fallback.createOrPropagate(t); + } catch (Exception e) { + throw propagate(e); + } + } + } + + private org.jclouds.Fallback getFallback(String commandName, Invocation invocation, HttpCommand command) { + HttpRequest request = command.getCurrentRequest(); + org.jclouds.Fallback fallback = config.getFallback(invocation); + if (fallback instanceof InvocationContext) + InvocationContext.class.cast(fallback).setContext(request); + logger.trace("<< exceptions from %s are parsed by %s", commandName, fallback.getClass().getSimpleName()); + return fallback; + } + + @VisibleForTesting + final class InvokeAndTransform implements Callable { + private final String commandName; + private final HttpCommand command; + private final Function transformer; + + InvokeAndTransform(String commandName, HttpCommand command) { + this.commandName = commandName; + this.command = command; + this.transformer = getTransformer(commandName, command); + } + + @Override + public Object call() throws Exception { + return transformer.apply(http.invoke(command)); + } + + @Override + public int hashCode() { + return Objects.hashCode(commandName, command, transformer); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + InvokeAndTransform that = InvokeAndTransform.class.cast(obj); + return equal(this.commandName, that.commandName) && equal(this.command, that.command) + && equal(this.transformer, that.transformer); + } + + @Override + public String toString() { + return toStringHelper(this).add("commandName", commandName).add("command", command) + .add("transformer", transformer).toString(); + } + } + + /** + * looks up the corresponding {@code Invocation} that returns a + * {@code Future}. Only Invokables that return {@code Futures} are annotated + * in a way that can be parsed into an {@linkplain HttpRequest}. + */ + private Invocation toAsync(Invocation in) { + Invocation async = sync2async.apply(in); + checkState(isFuture(async.getInvokable()), "not a future: %s", async); + return async; + } + + private HttpCommand toCommand(String commandName, Invocation invocation) { + logger.trace(">> converting %s", commandName); + HttpRequest request = annotationProcessor.apply(invocation); + logger.trace("<< converted %s to %s", commandName, request.getRequestLine()); + return new HttpCommand(request); + } + + private Function getTransformer(String commandName, HttpCommand command) { + HttpRequest request = command.getCurrentRequest(); + Function transformer = transformerForRequest.apply(request); + logger.trace("<< response from %s is parsed by %s", commandName, transformer.getClass().getSimpleName()); + return transformer; + } + + private boolean isFuture(Invokable in) { + return in.getReturnType().getRawType().equals(ListenableFuture.class); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + InvokeSyncToAsyncHttpMethod that = InvokeSyncToAsyncHttpMethod.class.cast(o); + return equal(this.annotationProcessor, that.annotationProcessor); + } + + @Override + public int hashCode() { + return Objects.hashCode(annotationProcessor); + } + + @Override + public String toString() { + return Objects.toStringHelper("").omitNullValues().add("annotationParser", annotationProcessor).toString(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java b/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java index 8ac824667a..5dd2bb1f39 100644 --- a/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java +++ b/core/src/main/java/org/jclouds/rest/internal/UtilsImpl.java @@ -29,7 +29,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.rest.Utils; import org.jclouds.xml.XMLParser; @@ -48,7 +47,7 @@ public class UtilsImpl implements Utils { private final Json json; private final HttpClient simpleClient; - private final HttpAsyncClient simpleAsyncClient; + private final org.jclouds.rest.HttpAsyncClient simpleAsyncClient; private final Crypto encryption; private final DateService date; private final ListeningExecutorService userExecutor; @@ -60,7 +59,7 @@ public class UtilsImpl implements Utils { private XMLParser xml; @Inject - protected UtilsImpl(Injector injector, Json json, XMLParser xml, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient, + protected 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 credentialStore, LoggerFactory loggerFactory) { @@ -79,7 +78,8 @@ public class UtilsImpl implements Utils { } @Override - public HttpAsyncClient asyncHttp() { + @Deprecated + public org.jclouds.rest.HttpAsyncClient asyncHttp() { return simpleAsyncClient; } @@ -104,7 +104,8 @@ public class UtilsImpl implements Utils { } @Override - public HttpAsyncClient getHttpAsyncClient() { + @Deprecated + public org.jclouds.rest.HttpAsyncClient getHttpAsyncClient() { return simpleAsyncClient; } diff --git a/core/src/test/java/org/jclouds/config/BindApiContextWithWildcardExtendsExplicitAndRawTypeTest.java b/core/src/test/java/org/jclouds/config/BindApiContextWithWildcardExtendsExplicitAndRawTypeTest.java new file mode 100644 index 0000000000..ed078a23c3 --- /dev/null +++ b/core/src/test/java/org/jclouds/config/BindApiContextWithWildcardExtendsExplicitAndRawTypeTest.java @@ -0,0 +1,123 @@ +/** + * 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.Suppliers.ofInstance; +import static org.easymock.EasyMock.createMock; +import static org.testng.Assert.assertEquals; + +import javax.inject.Inject; + +import org.jclouds.Context; +import org.jclouds.domain.Credentials; +import org.jclouds.http.IntegrationTestAsyncClient; +import org.jclouds.http.IntegrationTestClient; +import org.jclouds.providers.AnonymousProviderMetadata; +import org.jclouds.providers.ProviderMetadata; +import org.jclouds.providers.config.BindProviderMetadataContextAndCredentials; +import org.jclouds.rest.ApiContext; +import org.jclouds.rest.HttpApiMetadata; +import org.jclouds.rest.Utils; +import org.jclouds.rest.internal.BaseRestApiTest.MockModule; +import org.testng.annotations.Test; + +import com.google.common.reflect.TypeToken; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "BindApiContextWithWildcardExtendsExplicitAndRawTypeTest") +public class BindApiContextWithWildcardExtendsExplicitAndRawTypeTest { + + @SuppressWarnings("rawtypes") + private static class ExpectedBindings { + + private final ApiContext raw; + private final ApiContext explicit; + + @Inject + public ExpectedBindings(ApiContext raw, ApiContext explicit) { + this.raw = raw; + this.explicit = explicit; + } + + } + + @Test + public void testRawAndExplicit() { + ProviderMetadata md = AnonymousProviderMetadata.forApiOnEndpoint(IntegrationTestClient.class, "http://localhost"); + + ExpectedBindings bindings = injectorFor(md).getInstance(ExpectedBindings.class); + assertEquals(bindings.raw, bindings.explicit); + } + + private Injector injectorFor(ProviderMetadata md) { + return Guice.createInjector(new BindNameToContext("test"), new BindProviderMetadataContextAndCredentials(md, + ofInstance(new Credentials("user", "pass"))), new BindApiContextWithWildcardExtendsExplicitAndRawType( + HttpApiMetadata.class.cast(md.getApiMetadata())), + + // stuff needed for ApiContextImpl + new MockModule(), new AbstractModule() { + + @Override + protected void configure() { + bind(Utils.class).toInstance(createMock(Utils.class)); + bind(IntegrationTestClient.class).toInstance(createMock(IntegrationTestClient.class)); + bind(IntegrationTestAsyncClient.class).toInstance(createMock(IntegrationTestAsyncClient.class)); + } + }); + } + + @SuppressWarnings("rawtypes") + private static class ExpectedBindingsWithWildCardExtends { + + private final ApiContext raw; + private final ApiContext explicit; + private final ApiContext wildcardExtends; + + @Inject + public ExpectedBindingsWithWildCardExtends(ApiContext raw, ApiContext explicit, + ApiContext wildcardExtends) { + this.raw = raw; + this.explicit = explicit; + this.wildcardExtends = wildcardExtends; + } + + } + + @Test + public void testRawExplicitAndWildCardExtends() { + ProviderMetadata md = AnonymousProviderMetadata.forApiOnEndpoint(IntegrationTestClient.class, "http://localhost"); + + TypeToken wildCardExtendsType = new TypeToken>() { + private static final long serialVersionUID = 1L; + }; + + md = md.toBuilder().apiMetadata(md.getApiMetadata().toBuilder().context(wildCardExtendsType).build()).build(); + + ExpectedBindingsWithWildCardExtends bindings = injectorFor(md).getInstance( + ExpectedBindingsWithWildCardExtends.class); + assertEquals(bindings.raw, bindings.explicit); + assertEquals(bindings.explicit, bindings.wildcardExtends); + } +} diff --git a/core/src/test/java/org/jclouds/http/IntegrationTestClient.java b/core/src/test/java/org/jclouds/http/IntegrationTestClient.java index 822abb12de..f1119637fc 100644 --- a/core/src/test/java/org/jclouds/http/IntegrationTestClient.java +++ b/core/src/test/java/org/jclouds/http/IntegrationTestClient.java @@ -18,12 +18,42 @@ */ package org.jclouds.http; -import java.io.Closeable; +import static com.google.common.util.concurrent.Futures.immediateFuture; +import java.io.Closeable; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.inject.Singleton; +import javax.ws.rs.GET; +import javax.ws.rs.HEAD; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.HttpMethod; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +import org.jclouds.Fallbacks.FalseOnNotFoundOr404; +import org.jclouds.http.functions.ParseSax; import org.jclouds.http.options.HttpRequestOptions; import org.jclouds.io.Payload; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.PayloadParam; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.rest.binders.BindToJsonPayload; +import org.jclouds.rest.binders.BindToStringPayload; +import org.jclouds.util.Strings2; +import com.google.common.base.Function; import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.ListenableFuture; import com.google.inject.Provides; /** @@ -32,37 +62,144 @@ import com.google.inject.Provides; * @author Adrian Cole */ public interface IntegrationTestClient extends Closeable { - String rowdy(String path); + @Target({ ElementType.METHOD }) + @Retention(RetentionPolicy.RUNTIME) + @HttpMethod("ROWDY") + public @interface ROWDY { + } - boolean exists(String path); + @ROWDY + @Path("/objects/{id}") + String rowdy(@PathParam("id") String path); - String synch(String id); + @HEAD + @Path("/objects/{id}") + @Fallback(FalseOnNotFoundOr404.class) + boolean exists(@PathParam("id") String path); - String download(String id); + @GET + @Path("/objects/{id}") + String download(@PathParam("id") String id); HttpResponse invoke(HttpRequest request); + + @GET + @Path("/{path}") + String synch(@PathParam("path") String id); - String downloadException(String id, HttpRequestOptions options); + @GET + @Path("/objects/{id}") + @Fallback(FooOnException.class) + String downloadException(@PathParam("id") String id, HttpRequestOptions options); - String synchException(String id, String header); + static class FooOnException implements org.jclouds.Fallback { + public ListenableFuture create(Throwable t) throws Exception { + return immediateFuture("foo"); + } - String upload(String id, String toPut); + public String createOrPropagate(Throwable t) throws Exception { + return "foo"; + } + } - String post(String id, String toPut); + @GET + @Path("/objects/{id}") + @Fallback(FooOnException.class) + String synchException(@PathParam("id") String id, @HeaderParam("Range") String header); - String postAsInputStream(String id, String toPut); + @PUT + @Path("/objects/{id}") + String upload(@PathParam("id") String id, @BinderParam(BindToStringPayload.class) String toPut); - Multimap postPayloadAndReturnHeaders(String id, Payload payload); + @POST + @Path("/objects/{id}") + String post(@PathParam("id") String id, @BinderParam(BindToStringPayload.class) String toPut); - String postJson(String id, String toPut); + @POST + @Path("/objects/{id}") + String postAsInputStream(@PathParam("id") String id, + @BinderParam(BindToInputStreamPayload.class) String toPut); - String downloadFilter(String id, String header); + static class BindToInputStreamPayload extends BindToStringPayload { + @Override + public R bindToRequest(R request, Object payload) { + request.setPayload(Strings2.toInputStream(payload.toString())); + request.getPayload().getContentMetadata().setContentLength((long) payload.toString().getBytes().length); + return request; + } + } - String download(String id, String header); + @Singleton + static class ResponsePayload implements Function> { - String downloadAndParse(String id); + public Multimap apply(HttpResponse from) { + return from.getHeaders(); + } - void putNothing(String id); + } + + @POST + @Path("/objects/{id}") + @ResponseParser(ResponsePayload.class) + Multimap postPayloadAndReturnHeaders(@PathParam("id") String id, Payload payload); + + @POST + @Path("/objects/{id}") + @MapBinder(BindToJsonPayload.class) + String postJson(@PathParam("id") String id, @PayloadParam("key") String toPut); + + @GET + @Path("/objects/{id}") + @RequestFilters(Filter.class) + String downloadFilter(@PathParam("id") String id, @HeaderParam("filterme") String header); + + static class Filter implements HttpRequestFilter { + public HttpRequest filter(HttpRequest request) throws HttpException { + if (request.getHeaders().containsKey("filterme")) { + request = request.toBuilder().replaceHeader("test", "test").build(); + } + return request; + } + } + + @GET + @Path("/objects/{id}") + String download(@PathParam("id") String id, @HeaderParam("test") String header); + + @GET + @Path("/objects/{id}") + @XMLResponseParser(BarHandler.class) + String downloadAndParse(@PathParam("id") String id); + + public static class BarHandler extends ParseSax.HandlerWithResult { + + private String bar = null; + private StringBuilder currentText = new StringBuilder(); + + @Override + public void endElement(String uri, String name, String qName) { + if (qName.equals("bar")) { + bar = currentText.toString(); + } + currentText = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + + } + + @Override + public String getResult() { + return bar; + } + + } + + @PUT + @Path("/objects/{id}") + void putNothing(@PathParam("id") String id); @Provides StringBuilder newStringBuilder(); diff --git a/core/src/test/java/org/jclouds/rest/config/RestModuleTest.java b/core/src/test/java/org/jclouds/rest/config/MappedHttpInvocationModuleTest.java similarity index 88% rename from core/src/test/java/org/jclouds/rest/config/RestModuleTest.java rename to core/src/test/java/org/jclouds/rest/config/MappedHttpInvocationModuleTest.java index 0a48f1e8c1..1460ec56db 100644 --- a/core/src/test/java/org/jclouds/rest/config/RestModuleTest.java +++ b/core/src/test/java/org/jclouds/rest/config/MappedHttpInvocationModuleTest.java @@ -43,7 +43,7 @@ import com.google.common.util.concurrent.ListenableFuture; * @author Adrian Cole */ @Test(groups = "unit") -public class RestModuleTest { +public class MappedHttpInvocationModuleTest { static interface Sync { String get(); } @@ -54,7 +54,7 @@ public class RestModuleTest { public void testPutInvokablesWhenInterfacesMatch() { Cache, Invokable> cache = CacheBuilder.newBuilder().build(); - RestModule.putInvokables(Sync.class, Async.class, cache); + SyncToAsyncHttpInvocationModule.putInvokables(Sync.class, Async.class, cache); assertEquals(cache.size(), 1); @@ -78,7 +78,7 @@ public class RestModuleTest { @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".* has different typed exceptions than target .*") public void testPutInvokablesWhenInterfacesMatchExceptExceptions() { Cache, Invokable> cache = CacheBuilder.newBuilder().build(); - RestModule.putInvokables(Sync.class, AsyncWithException.class, cache); + SyncToAsyncHttpInvocationModule.putInvokables(Sync.class, AsyncWithException.class, cache); } private static interface AsyncWithMisnamedMethod { @@ -88,7 +88,7 @@ public class RestModuleTest { @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "no such method .*") public void testPutInvokablesWhenTargetMethodNotFound() { Cache, Invokable> cache = CacheBuilder.newBuilder().build(); - RestModule.putInvokables(Sync.class, AsyncWithMisnamedMethod.class, cache); + SyncToAsyncHttpInvocationModule.putInvokables(Sync.class, AsyncWithMisnamedMethod.class, cache); } static final Predicate, Invokable>> isHttpInvokable = new Predicate, Invokable>>() { @@ -99,7 +99,7 @@ public class RestModuleTest { }; public void testSeedKnownSync2AsyncIncludesHttpClientByDefault() { - Map, Invokable> cache = RestModule.seedKnownSync2AsyncInvokables( + Map, Invokable> cache = SyncToAsyncHttpInvocationModule.seedKnownSync2AsyncInvokables( ImmutableMap., Class> of()).asMap(); assertEquals(cache.size(), 6); @@ -107,7 +107,7 @@ public class RestModuleTest { } public void testSeedKnownSync2AsyncInvokablesInterfacesMatch() { - Map, Invokable> cache = RestModule.seedKnownSync2AsyncInvokables( + Map, Invokable> cache = SyncToAsyncHttpInvocationModule.seedKnownSync2AsyncInvokables( ImmutableMap., Class> of(Sync.class, Async.class)).asMap(); assertEquals(cache.size(), 7); diff --git a/core/src/test/java/org/jclouds/rest/internal/BaseHttpApiMetadataTest.java b/core/src/test/java/org/jclouds/rest/internal/BaseHttpApiMetadataTest.java new file mode 100644 index 0000000000..2a588673be --- /dev/null +++ b/core/src/test/java/org/jclouds/rest/internal/BaseHttpApiMetadataTest.java @@ -0,0 +1,52 @@ +/** + * 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.internal; +import static org.jclouds.reflect.Reflection2.typeToken; + +import java.util.Set; + +import org.jclouds.View; +import org.jclouds.apis.ApiMetadata; +import org.jclouds.apis.Apis; +import org.jclouds.apis.internal.BaseApiMetadataTest; +import org.jclouds.rest.ApiContext; +import org.jclouds.rest.HttpApiMetadata; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.TypeToken; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit") +public abstract class BaseHttpApiMetadataTest extends BaseApiMetadataTest { + + public BaseHttpApiMetadataTest(HttpApiMetadata toTest, Set> views) { + super(toTest, views); + } + + @Test + public void testContextAssignableFromRestContext() { + Set all = ImmutableSet.copyOf(Apis.contextAssignableFrom(typeToken(ApiContext.class))); + assert all.contains(toTest) : String.format("%s not found in %s", toTest, all); + } + +} diff --git a/core/src/test/java/org/jclouds/rest/internal/BaseRestApiExpectTest.java b/core/src/test/java/org/jclouds/rest/internal/BaseRestApiExpectTest.java index 4154bab67e..b857ced9fa 100644 --- a/core/src/test/java/org/jclouds/rest/internal/BaseRestApiExpectTest.java +++ b/core/src/test/java/org/jclouds/rest/internal/BaseRestApiExpectTest.java @@ -70,7 +70,7 @@ import org.jclouds.io.Payload; import org.jclouds.io.Payloads; import org.jclouds.logging.config.NullLoggingModule; import org.jclouds.providers.ProviderMetadata; -import org.jclouds.rest.RestApiMetadata; +import org.jclouds.rest.HttpApiMetadata; import org.jclouds.rest.config.CredentialStoreModule; import org.jclouds.util.Strings2; import org.w3c.dom.Node; @@ -557,11 +557,16 @@ public abstract class BaseRestApiExpectTest { ApiMetadata am = (pm != null) ? pm.getApiMetadata() : checkNotNull(createApiMetadata(), "either createApiMetadata or createProviderMetadata must be overridden"); - builder = pm != null ? ContextBuilder.newBuilder(pm) : ContextBuilder.newBuilder(RestApiMetadata.class.cast(am)); + builder = pm != null ? ContextBuilder.newBuilder(pm) : ContextBuilder.newBuilder(am); + } + ApiMetadata am = builder.getApiMetadata(); + if (am instanceof HttpApiMetadata) { + this.api = HttpApiMetadata.class.cast(am).getApi(); + } else if (am instanceof org.jclouds.rest.RestApiMetadata) { + this.api = org.jclouds.rest.RestApiMetadata.class.cast(am).getApi(); + } else { + throw new UnsupportedOperationException("unsupported base type: " + am); } - - this.api = RestApiMetadata.class.cast(builder.getApiMetadata()).getApi(); - // isolate tests from eachother, as default credentialStore is static return builder.credentials(identity, credential).modules( ImmutableSet.of(new ExpectModule(fn), new NullLoggingModule(), new CredentialStoreModule(new CopyInputStreamInputSupplierMap( diff --git a/core/src/test/java/org/jclouds/rest/internal/InvokeHttpMethodTest.java b/core/src/test/java/org/jclouds/rest/internal/InvokeHttpMethodTest.java index 71dade0220..dc9f5eca2f 100644 --- a/core/src/test/java/org/jclouds/rest/internal/InvokeHttpMethodTest.java +++ b/core/src/test/java/org/jclouds/rest/internal/InvokeHttpMethodTest.java @@ -18,9 +18,7 @@ */ package org.jclouds.rest.internal; -import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; @@ -48,10 +46,7 @@ import com.google.common.base.Functions; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.TimeLimiter; /** @@ -62,17 +57,11 @@ import com.google.common.util.concurrent.TimeLimiter; public class InvokeHttpMethodTest { public static interface ThingApi { + @Named("ns:get") HttpResponse get(); } - public static interface ThingAsyncApi { - @Named("ns:get") - ListenableFuture get(); - } - private Invocation get; - private Invocation asyncGet; - private Function sync2async; private HttpRequest getRequest = HttpRequest.builder().method("GET").endpoint("http://get").build(); private HttpCommand getCommand = new HttpCommand(getRequest); private Function toRequest; @@ -80,15 +69,12 @@ public class InvokeHttpMethodTest { @BeforeClass void setupInvocations() throws SecurityException, NoSuchMethodException { get = Invocation.create(method(ThingApi.class, "get"), ImmutableList.of()); - asyncGet = Invocation.create(method(ThingAsyncApi.class, "get"), ImmutableList.of()); - sync2async = Functions.forMap(ImmutableMap.of(get, asyncGet)); - toRequest = Functions.forMap(ImmutableMap.of(asyncGet, getRequest)); + toRequest = Functions.forMap(ImmutableMap.of(get, getRequest)); } @SuppressWarnings("unchecked") private Function> transformerForRequest = Function.class.cast(Functions .constant(Functions.identity())); - private ListeningExecutorService userThreads = MoreExecutors.sameThreadExecutor(); private HttpResponse response = HttpResponse.builder().statusCode(200).payload("foo").build(); private HttpCommandExecutorService http; @@ -108,10 +94,9 @@ public class InvokeHttpMethodTest { fallback = createMock(org.jclouds.Fallback.class); config = createMock(InvocationConfig.class); future = createMock(ListenableFuture.class); - invokeHttpMethod = new InvokeHttpMethod(sync2async, toRequest, http, transformerForRequest, timeLimiter, config, - userThreads); - expect(config.getCommandName(asyncGet)).andReturn("ns:get"); - expect(config.getFallback(asyncGet)).andReturn(fallback); + invokeHttpMethod = new InvokeHttpMethod(toRequest, http, transformerForRequest, timeLimiter, config); + expect(config.getCommandName(get)).andReturn("ns:get"); + expect(config.getFallback(get)).andReturn(fallback); } @AfterMethod @@ -120,7 +105,7 @@ public class InvokeHttpMethodTest { } public void testMethodWithTimeoutRunsTimeLimiter() throws Exception { - expect(config.getTimeoutNanos(asyncGet)).andReturn(Optional.of(250000000l)); + expect(config.getTimeoutNanos(get)).andReturn(Optional.of(250000000l)); InvokeAndTransform invoke = invokeHttpMethod.new InvokeAndTransform("ns:get", getCommand); expect(timeLimiter.callWithTimeout(invoke, 250000000, TimeUnit.NANOSECONDS, true)).andReturn(response); replay(http, timeLimiter, fallback, config, future); @@ -128,24 +113,17 @@ public class InvokeHttpMethodTest { } public void testMethodWithNoTimeoutCallGetDirectly() throws Exception { - expect(config.getTimeoutNanos(asyncGet)).andReturn(Optional. absent()); + expect(config.getTimeoutNanos(get)).andReturn(Optional. absent()); expect(http.invoke(new HttpCommand(getRequest))).andReturn(response); replay(http, timeLimiter, fallback, config, future); invokeHttpMethod.apply(get); } - public void testAsyncMethodSubmitsRequest() throws Exception { - expect(http.submit(new HttpCommand(getRequest))).andReturn(future); - future.addListener(anyObject(Runnable.class), eq(userThreads)); - replay(http, timeLimiter, fallback, config, future); - invokeHttpMethod.apply(asyncGet); - } - private HttpResponse fallbackResponse = HttpResponse.builder().statusCode(200).payload("bar").build(); public void testDirectCallRunsFallbackCreateOrPropagate() throws Exception { IllegalStateException exception = new IllegalStateException(); - expect(config.getTimeoutNanos(asyncGet)).andReturn(Optional. absent()); + expect(config.getTimeoutNanos(get)).andReturn(Optional. absent()); expect(http.invoke(new HttpCommand(getRequest))).andThrow(exception); expect(fallback.createOrPropagate(exception)).andReturn(fallbackResponse); replay(http, timeLimiter, fallback, config, future); @@ -154,24 +132,11 @@ public class InvokeHttpMethodTest { public void testTimeLimitedRunsFallbackCreateOrPropagate() throws Exception { IllegalStateException exception = new IllegalStateException(); - expect(config.getTimeoutNanos(asyncGet)).andReturn(Optional.of(250000000l)); + expect(config.getTimeoutNanos(get)).andReturn(Optional.of(250000000l)); InvokeAndTransform invoke = invokeHttpMethod.new InvokeAndTransform("ns:get", getCommand); expect(timeLimiter.callWithTimeout(invoke, 250000000, TimeUnit.NANOSECONDS, true)).andThrow(exception); expect(fallback.createOrPropagate(exception)).andReturn(fallbackResponse); replay(http, timeLimiter, fallback, config, future); assertEquals(invokeHttpMethod.apply(get), fallbackResponse); } - - @SuppressWarnings("unchecked") - public void testSubmitRunsFallbackCreateOnGet() throws Exception { - IllegalStateException exception = new IllegalStateException(); - expect(http.submit(new HttpCommand(getRequest))).andReturn( - Futures. immediateFailedFuture(exception)); - expect(fallback.create(exception)).andReturn(Futures. immediateFuture(fallbackResponse)); - // not using the field, as you can see above we are making an immediate - // failed future instead. - future = createMock(ListenableFuture.class); - replay(http, timeLimiter, fallback, config, future); - assertEquals(ListenableFuture.class.cast(invokeHttpMethod.apply(asyncGet)).get(), fallbackResponse); - } } diff --git a/core/src/test/java/org/jclouds/rest/internal/InvokeMappedHttpMethodTest.java b/core/src/test/java/org/jclouds/rest/internal/InvokeMappedHttpMethodTest.java new file mode 100644 index 0000000000..811a9bae5c --- /dev/null +++ b/core/src/test/java/org/jclouds/rest/internal/InvokeMappedHttpMethodTest.java @@ -0,0 +1,177 @@ +/** + * 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.internal; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.jclouds.reflect.Reflection2.method; +import static org.testng.Assert.assertEquals; + +import java.util.concurrent.TimeUnit; + +import javax.inject.Named; + +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpCommandExecutorService; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.reflect.Invocation; +import org.jclouds.rest.config.InvocationConfig; +import org.jclouds.rest.internal.InvokeSyncToAsyncHttpMethod.InvokeAndTransform; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Function; +import com.google.common.base.Functions; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.TimeLimiter; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", singleThreaded = true) +public class InvokeMappedHttpMethodTest { + + public static interface ThingApi { + HttpResponse get(); + } + + public static interface ThingAsyncApi { + @Named("ns:get") + ListenableFuture get(); + } + + private Invocation get; + private Invocation asyncGet; + private Function sync2async; + private HttpRequest getRequest = HttpRequest.builder().method("GET").endpoint("http://get").build(); + private HttpCommand getCommand = new HttpCommand(getRequest); + private Function toRequest; + + @BeforeClass + void setupInvocations() throws SecurityException, NoSuchMethodException { + get = Invocation.create(method(ThingApi.class, "get"), ImmutableList.of()); + asyncGet = Invocation.create(method(ThingAsyncApi.class, "get"), ImmutableList.of()); + sync2async = Functions.forMap(ImmutableMap.of(get, asyncGet)); + toRequest = Functions.forMap(ImmutableMap.of(asyncGet, getRequest)); + } + + @SuppressWarnings("unchecked") + private Function> transformerForRequest = Function.class.cast(Functions + .constant(Functions.identity())); + private ListeningExecutorService userThreads = MoreExecutors.sameThreadExecutor(); + + private HttpResponse response = HttpResponse.builder().statusCode(200).payload("foo").build(); + private HttpCommandExecutorService http; + private TimeLimiter timeLimiter; + @SuppressWarnings("rawtypes") + private org.jclouds.Fallback fallback; + private InvocationConfig config; + private InvokeSyncToAsyncHttpMethod invokeHttpMethod; + + private ListenableFuture future; + + @SuppressWarnings("unchecked") + @BeforeMethod + void createMocks() { + http = createMock(HttpCommandExecutorService.class); + timeLimiter = createMock(TimeLimiter.class); + fallback = createMock(org.jclouds.Fallback.class); + config = createMock(InvocationConfig.class); + future = createMock(ListenableFuture.class); + invokeHttpMethod = new InvokeSyncToAsyncHttpMethod(sync2async, toRequest, http, transformerForRequest, timeLimiter, config, + userThreads); + expect(config.getCommandName(asyncGet)).andReturn("ns:get"); + expect(config.getFallback(asyncGet)).andReturn(fallback); + } + + @AfterMethod + void verifyMocks() { + verify(http, timeLimiter, fallback, config, future); + } + + public void testMethodWithTimeoutRunsTimeLimiter() throws Exception { + expect(config.getTimeoutNanos(asyncGet)).andReturn(Optional.of(250000000l)); + InvokeAndTransform invoke = invokeHttpMethod.new InvokeAndTransform("ns:get", getCommand); + expect(timeLimiter.callWithTimeout(invoke, 250000000, TimeUnit.NANOSECONDS, true)).andReturn(response); + replay(http, timeLimiter, fallback, config, future); + invokeHttpMethod.apply(get); + } + + public void testMethodWithNoTimeoutCallGetDirectly() throws Exception { + expect(config.getTimeoutNanos(asyncGet)).andReturn(Optional. absent()); + expect(http.invoke(new HttpCommand(getRequest))).andReturn(response); + replay(http, timeLimiter, fallback, config, future); + invokeHttpMethod.apply(get); + } + + public void testAsyncMethodSubmitsRequest() throws Exception { + expect(http.submit(new HttpCommand(getRequest))).andReturn(future); + future.addListener(anyObject(Runnable.class), eq(userThreads)); + replay(http, timeLimiter, fallback, config, future); + invokeHttpMethod.apply(asyncGet); + } + + private HttpResponse fallbackResponse = HttpResponse.builder().statusCode(200).payload("bar").build(); + + public void testDirectCallRunsFallbackCreateOrPropagate() throws Exception { + IllegalStateException exception = new IllegalStateException(); + expect(config.getTimeoutNanos(asyncGet)).andReturn(Optional. absent()); + expect(http.invoke(new HttpCommand(getRequest))).andThrow(exception); + expect(fallback.createOrPropagate(exception)).andReturn(fallbackResponse); + replay(http, timeLimiter, fallback, config, future); + assertEquals(invokeHttpMethod.apply(get), fallbackResponse); + } + + public void testTimeLimitedRunsFallbackCreateOrPropagate() throws Exception { + IllegalStateException exception = new IllegalStateException(); + expect(config.getTimeoutNanos(asyncGet)).andReturn(Optional.of(250000000l)); + InvokeAndTransform invoke = invokeHttpMethod.new InvokeAndTransform("ns:get", getCommand); + expect(timeLimiter.callWithTimeout(invoke, 250000000, TimeUnit.NANOSECONDS, true)).andThrow(exception); + expect(fallback.createOrPropagate(exception)).andReturn(fallbackResponse); + replay(http, timeLimiter, fallback, config, future); + assertEquals(invokeHttpMethod.apply(get), fallbackResponse); + } + + @SuppressWarnings("unchecked") + public void testSubmitRunsFallbackCreateOnGet() throws Exception { + IllegalStateException exception = new IllegalStateException(); + expect(http.submit(new HttpCommand(getRequest))).andReturn( + Futures. immediateFailedFuture(exception)); + expect(fallback.create(exception)).andReturn(Futures. immediateFuture(fallbackResponse)); + // not using the field, as you can see above we are making an immediate + // failed future instead. + future = createMock(ListenableFuture.class); + replay(http, timeLimiter, fallback, config, future); + assertEquals(ListenableFuture.class.cast(invokeHttpMethod.apply(asyncGet)).get(), fallbackResponse); + } +} diff --git a/providers/dynect/src/main/java/org/jclouds/dynect/v3/DynECTApi.java b/providers/dynect/src/main/java/org/jclouds/dynect/v3/DynECTApi.java index fcf67780fb..19119f4f38 100644 --- a/providers/dynect/src/main/java/org/jclouds/dynect/v3/DynECTApi.java +++ b/providers/dynect/src/main/java/org/jclouds/dynect/v3/DynECTApi.java @@ -18,24 +18,34 @@ */ package org.jclouds.dynect.v3; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + import java.io.Closeable; +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 org.jclouds.Fallbacks.NullOnNotFoundOr404; import org.jclouds.dynect.v3.domain.Job; import org.jclouds.dynect.v3.features.RecordApi; import org.jclouds.dynect.v3.features.SessionApi; import org.jclouds.dynect.v3.features.ZoneApi; +import org.jclouds.dynect.v3.filters.AlwaysAddContentType; +import org.jclouds.dynect.v3.filters.SessionManager; import org.jclouds.javax.annotation.Nullable; import org.jclouds.rest.annotations.Delegate; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.RequestFilters; /** * Provides access to DynECT Managed DNS through the API2 api *

    * - * @see DynECTAsyncApi - * @see + * @see * @author Adrian Cole */ public interface DynECTApi extends Closeable { @@ -46,8 +56,15 @@ public interface DynECTApi extends Closeable { * The ID of the job * @return null, if not found */ + @Named("GetJob") + @GET + @Path("/Job/{jobId}") + @RequestFilters({ AlwaysAddContentType.class, SessionManager.class }) + @Headers(keys = "API-Version", values = "{jclouds.api-version}") + @Fallback(NullOnNotFoundOr404.class) + @Consumes(APPLICATION_JSON) @Nullable - Job getJob(long jobId); + Job getJob(@PathParam("jobId") long jobId); /** * Provides synchronous access to Session features. @@ -60,7 +77,7 @@ public interface DynECTApi extends Closeable { */ @Delegate ZoneApi getZoneApi(); - + /** * Provides synchronous access to Record features */ diff --git a/providers/dynect/src/main/java/org/jclouds/dynect/v3/DynECTApiMetadata.java b/providers/dynect/src/main/java/org/jclouds/dynect/v3/DynECTApiMetadata.java index 89be1afb5b..614d7faa4b 100644 --- a/providers/dynect/src/main/java/org/jclouds/dynect/v3/DynECTApiMetadata.java +++ b/providers/dynect/src/main/java/org/jclouds/dynect/v3/DynECTApiMetadata.java @@ -23,8 +23,8 @@ import java.util.Properties; import org.jclouds.apis.ApiMetadata; import org.jclouds.dynect.v3.config.DynECTParserModule; -import org.jclouds.dynect.v3.config.DynECTRestClientModule; -import org.jclouds.rest.internal.BaseRestApiMetadata; +import org.jclouds.dynect.v3.config.DynECTHttpApiModule; +import org.jclouds.rest.internal.BaseHttpApiMetadata; import com.google.common.collect.ImmutableSet; import com.google.inject.Module; @@ -34,10 +34,8 @@ import com.google.inject.Module; * * @author Adrian Cole */ -public class DynECTApiMetadata extends BaseRestApiMetadata { +public class DynECTApiMetadata extends BaseHttpApiMetadata { - public static final String ANONYMOUS_IDENTITY = "ANONYMOUS"; - @Override public Builder toBuilder() { return new Builder().fromApiMetadata(this); @@ -52,27 +50,24 @@ public class DynECTApiMetadata extends BaseRestApiMetadata { } public static Properties defaultProperties() { - Properties properties = BaseRestApiMetadata.defaultProperties(); + Properties properties = BaseHttpApiMetadata.defaultProperties(); return properties; } - public static class Builder extends BaseRestApiMetadata.Builder { + public static class Builder extends BaseHttpApiMetadata.Builder { protected Builder() { - super(DynECTApi.class, DynECTAsyncApi.class); id("dynect") .name("DynECT API2") - .identityName("Username (or " + ANONYMOUS_IDENTITY + " if anonymous)") - .defaultIdentity(ANONYMOUS_IDENTITY) - .credentialName("Password") - .defaultCredential(ANONYMOUS_IDENTITY) + .identityName("${customer}:${userName}") + .credentialName("${password}") .documentation(URI.create("https://manage.dynect.net/help/docs/api2/rest/")) .version("3.3.8") .defaultEndpoint("https://api2.dynect.net/REST") .defaultProperties(DynECTApiMetadata.defaultProperties()) .defaultModules(ImmutableSet.>builder() .add(DynECTParserModule.class) - .add(DynECTRestClientModule.class).build()); + .add(DynECTHttpApiModule.class).build()); } @Override diff --git a/providers/dynect/src/main/java/org/jclouds/dynect/v3/DynECTAsyncApi.java b/providers/dynect/src/main/java/org/jclouds/dynect/v3/DynECTAsyncApi.java deleted file mode 100644 index 14f86b234f..0000000000 --- a/providers/dynect/src/main/java/org/jclouds/dynect/v3/DynECTAsyncApi.java +++ /dev/null @@ -1,86 +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.dynect.v3; - -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; - -import java.io.Closeable; - -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 org.jclouds.Fallbacks.NullOnNotFoundOr404; -import org.jclouds.dynect.v3.domain.Job; -import org.jclouds.dynect.v3.features.RecordAsyncApi; -import org.jclouds.dynect.v3.features.SessionAsyncApi; -import org.jclouds.dynect.v3.features.ZoneAsyncApi; -import org.jclouds.dynect.v3.filters.AlwaysAddContentType; -import org.jclouds.dynect.v3.filters.SessionManager; -import org.jclouds.rest.annotations.Delegate; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.Headers; -import org.jclouds.rest.annotations.RequestFilters; - -import com.google.common.util.concurrent.ListenableFuture; - -/** - * Provides access to DynECT Managed DNS through the API2 api - *

    - * - * @see DynECTApi - * @see - * @author Adrian Cole - * @deprecated please use {@code org.jclouds.ContextBuilder#buildApi(DynECTApi.class)} as - * {@link DynECTAsyncApi} interface will be removed in jclouds 1.7. - */ - -public interface DynECTAsyncApi extends Closeable { - /** - * @see DynECTApi#getJob - */ - @Named("GetJob") - @GET - @Path("/Job/{jobId}") - @RequestFilters({ AlwaysAddContentType.class, SessionManager.class }) - @Headers(keys = "API-Version", values = "{jclouds.api-version}") - @Fallback(NullOnNotFoundOr404.class) - @Consumes(APPLICATION_JSON) - ListenableFuture getJob(@PathParam("jobId") long jobId); - - /** - * Provides asynchronous access to Session features. - */ - @Delegate - SessionAsyncApi getSessionApi(); - - /** - * Provides asynchronous access to Zone features. - */ - @Delegate - ZoneAsyncApi getZoneApi(); - - /** - * Provides asynchronous access to Record features - */ - @Delegate - RecordAsyncApi getRecordApiForZone(@PathParam("zone") String zone); -} diff --git a/providers/dynect/src/main/java/org/jclouds/dynect/v3/binders/CreateRecordBinder.java b/providers/dynect/src/main/java/org/jclouds/dynect/v3/binders/CreateRecordBinder.java new file mode 100644 index 0000000000..6efd16b65d --- /dev/null +++ b/providers/dynect/src/main/java/org/jclouds/dynect/v3/binders/CreateRecordBinder.java @@ -0,0 +1,55 @@ +/** + * 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.dynect.v3.binders; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.http.Uris.uriBuilder; + +import java.net.URI; + +import javax.inject.Inject; + +import org.jclouds.dynect.v3.domain.CreateRecord; +import org.jclouds.http.HttpRequest; +import org.jclouds.json.Json; +import org.jclouds.rest.Binder; + +import com.google.common.collect.ImmutableMap; + +public class CreateRecordBinder implements Binder { + private final Json json; + + @Inject + CreateRecordBinder(Json json){ + this.json = checkNotNull(json, "json"); + } + + @SuppressWarnings("unchecked") + @Override + public R bindToRequest(R request, Object arg) { + CreateRecord in = CreateRecord.class.cast(checkNotNull(arg, "record to create")); + URI path = uriBuilder(request.getEndpoint()) + .build(ImmutableMap. builder() + .put("type", in.getType()) + .put("fqdn", in.getFQDN()).build()); + return (R) request.toBuilder() + .endpoint(path) + .payload(json.toJson(ImmutableMap.of("rdata", in.getRData(), "ttl", in.getTTL()))).build(); + } +} diff --git a/providers/dynect/src/main/java/org/jclouds/dynect/v3/binders/RecordIdBinder.java b/providers/dynect/src/main/java/org/jclouds/dynect/v3/binders/RecordIdBinder.java new file mode 100644 index 0000000000..e2ed0fe70c --- /dev/null +++ b/providers/dynect/src/main/java/org/jclouds/dynect/v3/binders/RecordIdBinder.java @@ -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.dynect.v3.binders; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.http.Uris.uriBuilder; + +import java.net.URI; + +import org.jclouds.dynect.v3.domain.RecordId; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +import com.google.common.collect.ImmutableMap; + +public class RecordIdBinder implements Binder { + @SuppressWarnings("unchecked") + @Override + public R bindToRequest(R request, Object recordId) { + RecordId valueToAppend = RecordId.class.cast(checkNotNull(recordId, "recordId")); + URI path = uriBuilder(request.getEndpoint()).appendPath("/{type}Record/{zone}/{fqdn}/{id}").build( + ImmutableMap. builder() + .put("type", valueToAppend.getType()) + .put("zone", valueToAppend.getZone()) + .put("fqdn", valueToAppend.getFQDN()) + .put("id", valueToAppend.getId()).build()); + return (R) request.toBuilder().endpoint(path).build(); + } +} \ No newline at end of file diff --git a/providers/dynect/src/main/java/org/jclouds/dynect/v3/config/DynECTRestClientModule.java b/providers/dynect/src/main/java/org/jclouds/dynect/v3/config/DynECTHttpApiModule.java similarity index 77% rename from providers/dynect/src/main/java/org/jclouds/dynect/v3/config/DynECTRestClientModule.java rename to providers/dynect/src/main/java/org/jclouds/dynect/v3/config/DynECTHttpApiModule.java index dbfda6b6be..a20c5ef97c 100644 --- a/providers/dynect/src/main/java/org/jclouds/dynect/v3/config/DynECTRestClientModule.java +++ b/providers/dynect/src/main/java/org/jclouds/dynect/v3/config/DynECTHttpApiModule.java @@ -25,7 +25,6 @@ import java.io.IOException; import java.net.HttpURLConnection; import java.net.Proxy; import java.net.URI; -import java.util.Map; import javax.inject.Inject; import javax.inject.Named; @@ -36,13 +35,7 @@ import javax.net.ssl.SSLContext; import org.jclouds.Constants; import org.jclouds.concurrent.SingleThreaded; import org.jclouds.dynect.v3.DynECTApi; -import org.jclouds.dynect.v3.DynECTAsyncApi; -import org.jclouds.dynect.v3.features.RecordApi; -import org.jclouds.dynect.v3.features.RecordAsyncApi; import org.jclouds.dynect.v3.features.SessionApi; -import org.jclouds.dynect.v3.features.SessionAsyncApi; -import org.jclouds.dynect.v3.features.ZoneApi; -import org.jclouds.dynect.v3.features.ZoneAsyncApi; import org.jclouds.dynect.v3.filters.SessionManager; import org.jclouds.dynect.v3.handlers.DynECTErrorHandler; import org.jclouds.dynect.v3.handlers.GetJobRedirectionRetryHandler; @@ -60,12 +53,11 @@ import org.jclouds.http.handlers.RedirectionRetryHandler; import org.jclouds.http.internal.HttpWire; import org.jclouds.http.internal.JavaUrlHttpCommandExecutorService; import org.jclouds.io.ContentMetadataCodec; -import org.jclouds.rest.ConfiguresRestClient; -import org.jclouds.rest.config.RestClientModule; +import org.jclouds.rest.ConfiguresHttpApi; +import org.jclouds.rest.config.HttpApiModule; import com.google.common.base.Function; import com.google.common.base.Supplier; -import com.google.common.collect.ImmutableMap; import com.google.common.util.concurrent.ListeningExecutorService; /** @@ -73,18 +65,12 @@ import com.google.common.util.concurrent.ListeningExecutorService; * * @author Adrian Cole */ -@ConfiguresRestClient +@ConfiguresHttpApi // only one job at a time or error "This session already has a job running" @SingleThreaded -public class DynECTRestClientModule extends RestClientModule { +public class DynECTHttpApiModule extends HttpApiModule { - public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder() - .put(SessionApi.class, SessionAsyncApi.class) - .put(ZoneApi.class, ZoneAsyncApi.class) - .put(RecordApi.class, RecordAsyncApi.class).build(); - - public DynECTRestClientModule() { - super(DELEGATE_MAP); + public DynECTHttpApiModule() { } @Override @@ -105,16 +91,15 @@ public class DynECTRestClientModule extends RestClientModule list() throws JobStillRunningException; /** - * Retrieves a list of resource record ids for all records of the fqdn in the given zone + * Retrieves a list of resource record ids for all records of the fqdn in the + * given zone * * @throws JobStillRunningException * if a different job in the session is still running */ - FluentIterable listByFQDN(String fqdn) throws JobStillRunningException; + @Named("GetRecord") + @GET + @Path("/AllRecord/{zone}/{fqdn}") + @ResponseParser(ToRecordIds.class) + @Fallback(EmptyFluentIterableOnNotFoundOr404.class) + FluentIterable listByFQDN(@PathParam("fqdn") String fqdn) throws JobStillRunningException; /** - * Retrieves a list of resource record ids for all records of the fqdn and type in the given zone + * Retrieves a list of resource record ids for all records of the fqdn and + * type in the given zone * * @throws JobStillRunningException * if a different job in the session is still running */ - FluentIterable listByFQDNAndType(String fqdn, String type) throws JobStillRunningException; + @Named("GetRecord") + @GET + @Path("/{type}Record/{zone}/{fqdn}") + @ResponseParser(ToRecordIds.class) + @Fallback(EmptyFluentIterableOnNotFoundOr404.class) + FluentIterable listByFQDNAndType(@PathParam("fqdn") String fqdn, @PathParam("type") String type) + throws JobStillRunningException; /** - * Schedules addition of a new record into the current session. Calling {@link ZoneApi#publish(String)} will publish - * the zone, creating the record. + * Schedules addition of a new record into the current session. Calling + * {@link ZoneApi#publish(String)} will publish the zone, creating the + * record. * * @param newRecord * record to create @@ -79,20 +123,31 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Job scheduleCreate(CreateRecord newRecord) throws JobStillRunningException; + @Named("CreateRecord") + @POST + @Path("/{type}Record/{zone}/{fqdn}") + @Consumes(APPLICATION_JSON) + @Produces(APPLICATION_JSON) + Job scheduleCreate(@BinderParam(CreateRecordBinder.class) CreateRecord newRecord) throws JobStillRunningException; /** - * Schedules deletion of a record into the current session. Calling {@link ZoneApi#publish(String)} will publish the - * changes, deleting the record. + * Schedules deletion of a record into the current session. Calling + * {@link ZoneApi#publish(String)} will publish the changes, deleting the + * record. * * @param recordId * record to delete - * @return job relating to the scheduled deletion or null, if the record never existed. + * @return job relating to the scheduled deletion or null, if the record + * never existed. * @throws JobStillRunningException * if a different job in the session is still running */ @Nullable - Job scheduleDelete(RecordId recordId) throws JobStillRunningException; + @Named("DeleteRecord") + @DELETE + @Fallback(NullOnNotFoundOr404.class) + @Consumes(APPLICATION_JSON) + Job scheduleDelete(@BinderParam(RecordIdBinder.class) RecordId recordId) throws JobStillRunningException; /** * retrieves a resource record without regard to type @@ -101,7 +156,13 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Record> get(RecordId recordId) throws JobStillRunningException; + @Named("GetRecord") + @GET + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Record> get(@BinderParam(RecordIdBinder.class) RecordId recordId) + throws JobStillRunningException; /** * Gets the {@link AAAARecord} or null if not present. @@ -114,7 +175,14 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Record getAAAA(String fqdn, long recordId) throws JobStillRunningException; + @Named("GetAAAARecord") + @GET + @Path("/AAAARecord/{zone}/{fqdn}/{id}") + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Record getAAAA(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) + throws JobStillRunningException; /** * Gets the {@link ARecord} or null if not present. @@ -127,7 +195,13 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Record getA(String fqdn, long recordId) throws JobStillRunningException; + @Named("GetARecord") + @GET + @Path("/ARecord/{zone}/{fqdn}/{id}") + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Record getA(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; /** * Gets the {@link CNAMERecord} or null if not present. @@ -140,7 +214,14 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Record getCNAME(String fqdn, long recordId) throws JobStillRunningException; + @Named("GetCNAMERecord") + @GET + @Path("/CNAMERecord/{zone}/{fqdn}/{id}") + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Record getCNAME(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) + throws JobStillRunningException; /** * Gets the {@link MXRecord} or null if not present. @@ -153,7 +234,13 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Record getMX(String fqdn, long recordId) throws JobStillRunningException; + @Named("GetMXRecord") + @GET + @Path("/MXRecord/{zone}/{fqdn}/{id}") + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Record getMX(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; /** * Gets the {@link NSRecord} or null if not present. @@ -166,7 +253,13 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Record getNS(String fqdn, long recordId) throws JobStillRunningException; + @Named("GetNSRecord") + @GET + @Path("/NSRecord/{zone}/{fqdn}/{id}") + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Record getNS(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; /** * Gets the {@link PTRRecord} or null if not present. @@ -179,7 +272,14 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Record getPTR(String fqdn, long recordId) throws JobStillRunningException; + @Named("GetPTRRecord") + @GET + @Path("/PTRRecord/{zone}/{fqdn}/{id}") + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Record getPTR(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) + throws JobStillRunningException; /** * Gets the {@link SOARecord} or null if not present. @@ -192,7 +292,13 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - SOARecord getSOA(String fqdn, long recordId) throws JobStillRunningException; + @Named("GetSOARecord") + @GET + @Path("/SOARecord/{zone}/{fqdn}/{id}") + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + SOARecord getSOA(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; /** * Gets the {@link SPFRecord} or null if not present. @@ -205,7 +311,14 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Record getSPF(String fqdn, long recordId) throws JobStillRunningException; + @Named("GetSPFRecord") + @GET + @Path("/SPFRecord/{zone}/{fqdn}/{id}") + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Record getSPF(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) + throws JobStillRunningException; /** * Gets the {@link SRVRecord} or null if not present. @@ -218,7 +331,14 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Record getSRV(String fqdn, long recordId) throws JobStillRunningException; + @Named("GetSRVRecord") + @GET + @Path("/SRVRecord/{zone}/{fqdn}/{id}") + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Record getSRV(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) + throws JobStillRunningException; /** * Gets the {@link SSHFPRecord} or null if not present. @@ -231,7 +351,14 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Record getSSHFP(String fqdn, long recordId) throws JobStillRunningException; + @Named("GetSSHFPRecord") + @GET + @Path("/SSHFPRecord/{zone}/{fqdn}/{id}") + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Record getSSHFP(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) + throws JobStillRunningException; /** * Gets the {@link TXTRecord} or null if not present. @@ -244,5 +371,12 @@ public interface RecordApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Record getTXT(String fqdn, long recordId) throws JobStillRunningException; + @Named("GetTXTRecord") + @GET + @Path("/TXTRecord/{zone}/{fqdn}/{id}") + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Record getTXT(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) + throws JobStillRunningException; } \ No newline at end of file diff --git a/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/RecordAsyncApi.java b/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/RecordAsyncApi.java deleted file mode 100644 index b6badf12cc..0000000000 --- a/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/RecordAsyncApi.java +++ /dev/null @@ -1,291 +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, String 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.dynect.v3.features; - -import static com.google.common.base.Preconditions.checkNotNull; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; -import static org.jclouds.http.Uris.uriBuilder; - -import java.net.URI; -import java.util.Map; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; - -import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404; -import org.jclouds.Fallbacks.NullOnNotFoundOr404; -import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException; -import org.jclouds.dynect.v3.domain.CreateRecord; -import org.jclouds.dynect.v3.domain.Job; -import org.jclouds.dynect.v3.domain.Record; -import org.jclouds.dynect.v3.domain.RecordId; -import org.jclouds.dynect.v3.domain.SOARecord; -import org.jclouds.dynect.v3.domain.rdata.AAAAData; -import org.jclouds.dynect.v3.domain.rdata.AData; -import org.jclouds.dynect.v3.domain.rdata.CNAMEData; -import org.jclouds.dynect.v3.domain.rdata.MXData; -import org.jclouds.dynect.v3.domain.rdata.NSData; -import org.jclouds.dynect.v3.domain.rdata.PTRData; -import org.jclouds.dynect.v3.domain.rdata.SPFData; -import org.jclouds.dynect.v3.domain.rdata.SRVData; -import org.jclouds.dynect.v3.domain.rdata.SSHFPData; -import org.jclouds.dynect.v3.domain.rdata.TXTData; -import org.jclouds.dynect.v3.filters.AlwaysAddContentType; -import org.jclouds.dynect.v3.filters.SessionManager; -import org.jclouds.dynect.v3.functions.ToRecordIds; -import org.jclouds.http.HttpRequest; -import org.jclouds.json.Json; -import org.jclouds.rest.Binder; -import org.jclouds.rest.annotations.BinderParam; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.Headers; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.ResponseParser; -import org.jclouds.rest.annotations.SelectJson; - -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableMap; -import com.google.common.util.concurrent.ListenableFuture; - -/** - * - * @see RecordApi - * @see doc - * @author Adrian Cole - */ -@Headers(keys = "API-Version", values = "{jclouds.api-version}") -@RequestFilters({ AlwaysAddContentType.class, SessionManager.class }) -public interface RecordAsyncApi { - - /** - * @see RecordApi#list - */ - @Named("GetAllRecord") - @GET - @Path("/AllRecord/{zone}") - @ResponseParser(ToRecordIds.class) - ListenableFuture> list() throws JobStillRunningException; - - /** - * @see RecordApi#listByFQDN - */ - @Named("GetRecord") - @GET - @Path("/AllRecord/{zone}/{fqdn}") - @ResponseParser(ToRecordIds.class) - @Fallback(EmptyFluentIterableOnNotFoundOr404.class) - ListenableFuture> listByFQDN(@PathParam("fqdn") String fqdn) - throws JobStillRunningException; - - /** - * @see RecordApi#listByFQDNAndType - */ - @Named("GetRecord") - @GET - @Path("/{type}Record/{zone}/{fqdn}") - @ResponseParser(ToRecordIds.class) - @Fallback(EmptyFluentIterableOnNotFoundOr404.class) - ListenableFuture> listByFQDNAndType(@PathParam("fqdn") String fqdn, - @PathParam("type") String type) throws JobStillRunningException; - - /** - * @see RecordApi#scheduleCreate - */ - @Named("CreateRecord") - @POST - @Path("/{type}Record/{zone}/{fqdn}") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - ListenableFuture scheduleCreate(@BinderParam(CreateRecordBinder.class) CreateRecord newRecord) - throws JobStillRunningException; - - static class CreateRecordBinder implements Binder { - private final Json json; - - @Inject - CreateRecordBinder(Json json){ - this.json = checkNotNull(json, "json"); - } - - @SuppressWarnings("unchecked") - @Override - public R bindToRequest(R request, Object arg) { - CreateRecord in = CreateRecord.class.cast(checkNotNull(arg, "record to create")); - URI path = uriBuilder(request.getEndpoint()) - .build(ImmutableMap. builder() - .put("type", in.getType()) - .put("fqdn", in.getFQDN()).build()); - return (R) request.toBuilder() - .endpoint(path) - .payload(json.toJson(ImmutableMap.of("rdata", in.getRData(), "ttl", in.getTTL()))).build(); - } - } - - /** - * @see RecordApi#scheduleDelete - */ - @Named("DeleteRecord") - @DELETE - @Fallback(NullOnNotFoundOr404.class) - @Consumes(APPLICATION_JSON) - ListenableFuture scheduleDelete(@BinderParam(RecordIdBinder.class) RecordId recordId) throws JobStillRunningException; - - /** - * @see RecordApi#get - */ - @Named("GetRecord") - @GET - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture>> get(@BinderParam(RecordIdBinder.class) RecordId recordId) throws JobStillRunningException; - - static class RecordIdBinder implements Binder { - @SuppressWarnings("unchecked") - @Override - public R bindToRequest(R request, Object recordId) { - RecordId valueToAppend = RecordId.class.cast(checkNotNull(recordId, "recordId")); - URI path = uriBuilder(request.getEndpoint()) - .appendPath("/{type}Record/{zone}/{fqdn}/{id}") - .build(ImmutableMap. builder() - .put("type", valueToAppend.getType()) - .put("zone", valueToAppend.getZone()) - .put("fqdn", valueToAppend.getFQDN()) - .put("id", valueToAppend.getId()).build()); - return (R) request.toBuilder().endpoint(path).build(); - } - } - - /** - * @see RecordApi#getAAAA - */ - @Named("GetAAAARecord") - @GET - @Path("/AAAARecord/{zone}/{fqdn}/{id}") - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture> getAAAA(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; - - /** - * @see RecordApi#getA - */ - @Named("GetARecord") - @GET - @Path("/ARecord/{zone}/{fqdn}/{id}") - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture> getA(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; - - /** - * @see RecordApi#getCNAME - */ - @Named("GetCNAMERecord") - @GET - @Path("/CNAMERecord/{zone}/{fqdn}/{id}") - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture> getCNAME(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; - - /** - * @see RecordApi#getMX - */ - @Named("GetMXRecord") - @GET - @Path("/MXRecord/{zone}/{fqdn}/{id}") - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture> getMX(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; - - /** - * @see RecordApi#getNS - */ - @Named("GetNSRecord") - @GET - @Path("/NSRecord/{zone}/{fqdn}/{id}") - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture> getNS(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; - - /** - * @see RecordApi#getPTR - */ - @Named("GetPTRRecord") - @GET - @Path("/PTRRecord/{zone}/{fqdn}/{id}") - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture> getPTR(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; - - /** - * @see RecordApi#getSOA - */ - @Named("GetSOARecord") - @GET - @Path("/SOARecord/{zone}/{fqdn}/{id}") - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture getSOA(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; - - /** - * @see RecordApi#getSPF - */ - @Named("GetSPFRecord") - @GET - @Path("/SPFRecord/{zone}/{fqdn}/{id}") - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture> getSPF(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; - - /** - * @see RecordApi#getSRV - */ - @Named("GetSRVRecord") - @GET - @Path("/SRVRecord/{zone}/{fqdn}/{id}") - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture> getSRV(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; - - /** - * @see RecordApi#getSSHFP - */ - @Named("GetSSHFPRecord") - @GET - @Path("/SSHFPRecord/{zone}/{fqdn}/{id}") - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture> getSSHFP(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; - - /** - * @see RecordApi#getTXT - */ - @Named("GetTXTRecord") - @GET - @Path("/TXTRecord/{zone}/{fqdn}/{id}") - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture> getTXT(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException; -} diff --git a/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/SessionApi.java b/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/SessionApi.java index fc6fcf2816..ce0505b2df 100644 --- a/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/SessionApi.java +++ b/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/SessionApi.java @@ -18,21 +18,46 @@ */ package org.jclouds.dynect.v3.features; +import javax.inject.Named; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import org.jclouds.dynect.v3.DynECTFallbacks.FalseOn400; import org.jclouds.dynect.v3.domain.Session; import org.jclouds.dynect.v3.domain.SessionCredentials; +import org.jclouds.dynect.v3.filters.AlwaysAddContentType; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.Headers; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SelectJson; +import org.jclouds.rest.binders.BindToJsonPayload; /** - * @see SessionAsyncApi * @see * @author Adrian Cole */ +@Headers(keys = "API-Version", values = "{jclouds.api-version}") +@Path("/Session") +@RequestFilters(AlwaysAddContentType.class) public interface SessionApi { - Session login(SessionCredentials credentials); + @Named("POST:Session") + @POST + @SelectJson("data") + Session login(@BinderParam(BindToJsonPayload.class) SessionCredentials credentials); - boolean isValid(String token); + @Named("GET:Session") + @GET + @Fallback(FalseOn400.class) + boolean isValid(@HeaderParam("Auth-Token") String token); - void logout(String token); + @Named("DELETE:Session") + @DELETE + void logout(@HeaderParam("Auth-Token") String token); } \ No newline at end of file diff --git a/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/SessionAsyncApi.java b/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/SessionAsyncApi.java deleted file mode 100644 index 5eabd50f95..0000000000 --- a/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/SessionAsyncApi.java +++ /dev/null @@ -1,76 +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.dynect.v3.features; - -import javax.inject.Named; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; - -import org.jclouds.dynect.v3.DynECTFallbacks.FalseOn400; -import org.jclouds.dynect.v3.domain.Session; -import org.jclouds.dynect.v3.domain.SessionCredentials; -import org.jclouds.dynect.v3.filters.AlwaysAddContentType; -import org.jclouds.rest.annotations.BinderParam; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.Headers; -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 access to DynECT Managed DNS through the API2 api - *

    - * - * @see SessionApi - * @see - * @author Adrian Cole - */ -@Headers(keys = "API-Version", values = "{jclouds.api-version}") -@Path("/Session") -@RequestFilters(AlwaysAddContentType.class) -public interface SessionAsyncApi { - - /** - * @see SessionApi#create - */ - @Named("POST:Session") - @POST - @SelectJson("data") - ListenableFuture login(@BinderParam(BindToJsonPayload.class) SessionCredentials credentials); - - /** - * @see SessionApi#isValid - */ - @Named("GET:Session") - @GET - @Fallback(FalseOn400.class) - ListenableFuture isValid(@HeaderParam("Auth-Token") String token); - - /** - * @see SessionApi#logout - */ - @Named("DELETE:Session") - @DELETE - ListenableFuture logout(@HeaderParam("Auth-Token") String token); -} diff --git a/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/ZoneApi.java b/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/ZoneApi.java index 0ebde9fdc1..e90d1d4cef 100644 --- a/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/ZoneApi.java +++ b/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/ZoneApi.java @@ -18,21 +18,49 @@ */ package org.jclouds.dynect.v3.features; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +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 org.jclouds.Fallbacks.NullOnNotFoundOr404; import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException; import org.jclouds.dynect.v3.DynECTExceptions.TargetExistsException; import org.jclouds.dynect.v3.domain.CreatePrimaryZone; +import org.jclouds.dynect.v3.domain.CreatePrimaryZone.ToFQDN; import org.jclouds.dynect.v3.domain.Job; import org.jclouds.dynect.v3.domain.Zone; import org.jclouds.dynect.v3.domain.Zone.SerialStyle; +import org.jclouds.dynect.v3.filters.AlwaysAddContentType; +import org.jclouds.dynect.v3.filters.SessionManager; +import org.jclouds.dynect.v3.functions.ExtractZoneNames; import org.jclouds.javax.annotation.Nullable; import org.jclouds.rest.ResourceNotFoundException; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.Headers; +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.SelectJson; +import org.jclouds.rest.annotations.Transform; +import org.jclouds.rest.binders.BindToJsonPayload; import com.google.common.collect.FluentIterable; /** - * @see ZoneAsyncApi * @author Adrian Cole */ +@Headers(keys = "API-Version", values = "{jclouds.api-version}") +@RequestFilters({ AlwaysAddContentType.class, SessionManager.class }) public interface ZoneApi { /** * Lists all zone ids. @@ -40,11 +68,16 @@ public interface ZoneApi { * @throws JobStillRunningException * if a different job in the session is still running */ + @Named("ListZones") + @GET + @Path("/Zone") + @SelectJson("data") + @Transform(ExtractZoneNames.class) FluentIterable list() throws JobStillRunningException; /** - * Schedules addition of a new primary zone into the current session. Calling {@link ZoneApi#publish(String)} will - * publish the zone, creating the zone. + * Schedules addition of a new primary zone into the current session. Calling + * {@link ZoneApi#publish(String)} will publish the zone, creating the zone. * * @param zone * required parameters to create the zone. @@ -54,11 +87,18 @@ public interface ZoneApi { * @throws TargetExistsException * if the same fqdn exists */ - Job scheduleCreate(CreatePrimaryZone zone) throws JobStillRunningException, TargetExistsException; + @Named("CreatePrimaryZone") + @POST + @Path("/Zone/{fqdn}") + @Consumes(APPLICATION_JSON) + Job scheduleCreate( + @PathParam("fqdn") @ParamParser(ToFQDN.class) @BinderParam(BindToJsonPayload.class) CreatePrimaryZone createZone) + throws JobStillRunningException, TargetExistsException; /** - * Schedules addition of a new primary zone with one hour default TTL and {@link SerialStyle#INCREMENT} into the - * current session. Calling {@link ZoneApi#publish(String)} will publish the zone, creating the zone. + * Schedules addition of a new primary zone with one hour default TTL and + * {@link SerialStyle#INCREMENT} into the current session. Calling + * {@link ZoneApi#publish(String)} will publish the zone, creating the zone. * * @param fqdn * fqdn of the zone to create {@ex. jclouds.org} @@ -70,42 +110,65 @@ public interface ZoneApi { * @throws TargetExistsException * if the same fqdn exists */ - Job scheduleCreateWithContact(String fqdn, String contact) throws JobStillRunningException, TargetExistsException; + @Named("CreatePrimaryZone") + @POST + @Produces(APPLICATION_JSON) + @Payload("%7B\"rname\":\"{contact}\",\"serial_style\":\"increment\",\"ttl\":3600%7D") + @Path("/Zone/{fqdn}") + @Consumes(APPLICATION_JSON) + Job scheduleCreateWithContact(@PathParam("fqdn") String fqdn, @PayloadParam("contact") String contact) + throws JobStillRunningException, TargetExistsException; /** * Retrieves information about the specified zone. * * @param fqdn - * fqdn of the zone to get information about. ex {@code jclouds.org} + * fqdn of the zone to get information about. ex + * {@code jclouds.org} * @return null if not found * @throws JobStillRunningException * if a different job in the session is still running */ + @Named("GetZone") + @GET + @Path("/Zone/{fqdn}") + @SelectJson("data") + @Fallback(NullOnNotFoundOr404.class) @Nullable - Zone get(String fqdn) throws JobStillRunningException; + Zone get(@PathParam("fqdn") String fqdn) throws JobStillRunningException; /** - * Deletes the zone. No need to call @link ZoneApi#publish(String)}. + * Deletes the zone. No need to call @link ZoneApi#publish(String)}. * * @param fqdn * zone to delete - * @return job relating to the scheduled deletion or null, if the zone never existed. + * @return job relating to the scheduled deletion or null, if the zone never + * existed. * @throws JobStillRunningException * if a different job in the session is still running */ + @Named("DeleteZone") + @DELETE + @Path("/Zone/{fqdn}") + @Fallback(NullOnNotFoundOr404.class) + @Consumes(APPLICATION_JSON) @Nullable - Job delete(String fqdn) throws JobStillRunningException; + Job delete(@PathParam("fqdn") String fqdn) throws JobStillRunningException; /** - * Deletes changes to the specified zone that have been created during the current session but not yet published to - * the zone. + * Deletes changes to the specified zone that have been created during the + * current session but not yet published to the zone. * * @param fqdn * fqdn of the zone to delete changes from ex {@code jclouds.org} * @throws JobStillRunningException * if a different job in the session is still running */ - Job deleteChanges(String fqdn) throws JobStillRunningException; + @Named("DeleteZoneChanges") + @DELETE + @Path("/ZoneChanges/{fqdn}") + @Consumes(APPLICATION_JSON) + Job deleteChanges(@PathParam("fqdn") String fqdn) throws JobStillRunningException; /** * Publishes the current zone @@ -117,7 +180,13 @@ public interface ZoneApi { * @throws ResourceNotFoundException * if the zone doesn't exist */ - Zone publish(String fqdn) throws JobStillRunningException, ResourceNotFoundException; + @Named("PublishZone") + @PUT + @Path("/Zone/{fqdn}") + @Produces(APPLICATION_JSON) + @Payload("{\"publish\":true}") + @SelectJson("data") + Zone publish(@PathParam("fqdn") String fqdn) throws JobStillRunningException, ResourceNotFoundException; /** * freezes the specified zone. @@ -127,7 +196,13 @@ public interface ZoneApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Job freeze(String fqdn) throws JobStillRunningException; + @Named("FreezeZone") + @PUT + @Path("/Zone/{fqdn}") + @Produces(APPLICATION_JSON) + @Payload("{\"freeze\":true}") + @Consumes(APPLICATION_JSON) + Job freeze(@PathParam("fqdn") String fqdn) throws JobStillRunningException; /** * thaws the specified zone. @@ -137,5 +212,11 @@ public interface ZoneApi { * @throws JobStillRunningException * if a different job in the session is still running */ - Job thaw(String fqdn) throws JobStillRunningException; + @Named("ThawZone") + @PUT + @Path("/Zone/{fqdn}") + @Produces(APPLICATION_JSON) + @Payload("{\"thaw\":true}") + @Consumes(APPLICATION_JSON) + Job thaw(@PathParam("fqdn") String fqdn) throws JobStillRunningException; } \ No newline at end of file diff --git a/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/ZoneAsyncApi.java b/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/ZoneAsyncApi.java deleted file mode 100644 index 8569b814be..0000000000 --- a/providers/dynect/src/main/java/org/jclouds/dynect/v3/features/ZoneAsyncApi.java +++ /dev/null @@ -1,163 +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, String 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.dynect.v3.features; - -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; - -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 org.jclouds.Fallbacks.NullOnNotFoundOr404; -import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException; -import org.jclouds.dynect.v3.DynECTExceptions.TargetExistsException; -import org.jclouds.dynect.v3.domain.CreatePrimaryZone; -import org.jclouds.dynect.v3.domain.CreatePrimaryZone.ToFQDN; -import org.jclouds.dynect.v3.domain.Job; -import org.jclouds.dynect.v3.domain.Zone; -import org.jclouds.dynect.v3.filters.AlwaysAddContentType; -import org.jclouds.dynect.v3.filters.SessionManager; -import org.jclouds.dynect.v3.functions.ExtractZoneNames; -import org.jclouds.rest.ResourceNotFoundException; -import org.jclouds.rest.annotations.BinderParam; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.Headers; -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.SelectJson; -import org.jclouds.rest.annotations.Transform; -import org.jclouds.rest.binders.BindToJsonPayload; - -import com.google.common.collect.FluentIterable; -import com.google.common.util.concurrent.ListenableFuture; - -/** - * - * @see ZoneApi - * @see doc - * @author Adrian Cole - */ -@Headers(keys = "API-Version", values = "{jclouds.api-version}") -@RequestFilters({ AlwaysAddContentType.class, SessionManager.class }) -public interface ZoneAsyncApi { - - /** - * @see ZoneApi#list - */ - @Named("ListZones") - @GET - @Path("/Zone") - @SelectJson("data") - @Transform(ExtractZoneNames.class) - ListenableFuture> list() throws JobStillRunningException; - - /** - * @see ZoneApi#get - */ - @Named("GetZone") - @GET - @Path("/Zone/{fqdn}") - @SelectJson("data") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture get(@PathParam("fqdn") String fqdn) throws JobStillRunningException; - - /** - * @see ZoneApi#scheduleCreate - */ - @Named("CreatePrimaryZone") - @POST - @Path("/Zone/{fqdn}") - @Consumes(APPLICATION_JSON) - ListenableFuture scheduleCreate( - @PathParam("fqdn") @ParamParser(ToFQDN.class) @BinderParam(BindToJsonPayload.class) CreatePrimaryZone createZone) - throws JobStillRunningException, TargetExistsException; - - /** - * @see ZoneApi#scheduleCreateWithContact - */ - @Named("CreatePrimaryZone") - @POST - @Produces(APPLICATION_JSON) - @Payload("%7B\"rname\":\"{contact}\",\"serial_style\":\"increment\",\"ttl\":3600%7D") - @Path("/Zone/{fqdn}") - @Consumes(APPLICATION_JSON) - ListenableFuture scheduleCreateWithContact(@PathParam("fqdn") String fqdn, - @PayloadParam("contact") String contact) throws JobStillRunningException, TargetExistsException; - - /** - * @see ZoneApi#delete - */ - @Named("DeleteZone") - @DELETE - @Path("/Zone/{fqdn}") - @Fallback(NullOnNotFoundOr404.class) - @Consumes(APPLICATION_JSON) - ListenableFuture delete(@PathParam("fqdn") String fqdn) throws JobStillRunningException; - - /** - * @see ZoneApi#deleteChanges - */ - @Named("DeleteZoneChanges") - @DELETE - @Path("/ZoneChanges/{fqdn}") - @Consumes(APPLICATION_JSON) - ListenableFuture deleteChanges(@PathParam("fqdn") String fqdn) throws JobStillRunningException; - - /** - * @see ZoneApi#publish - */ - @Named("PublishZone") - @PUT - @Path("/Zone/{fqdn}") - @Produces(APPLICATION_JSON) - @Payload("{\"publish\":true}") - @SelectJson("data") - ListenableFuture publish(@PathParam("fqdn") String fqdn) throws JobStillRunningException, ResourceNotFoundException; - - /** - * @see ZoneApi#freeze - */ - @Named("FreezeZone") - @PUT - @Path("/Zone/{fqdn}") - @Produces(APPLICATION_JSON) - @Payload("{\"freeze\":true}") - @Consumes(APPLICATION_JSON) - ListenableFuture freeze(@PathParam("fqdn") String fqdn) throws JobStillRunningException; - - /** - * @see ZoneApi#thaw - */ - @Named("ThawZone") - @PUT - @Path("/Zone/{fqdn}") - @Produces(APPLICATION_JSON) - @Payload("{\"thaw\":true}") - @Consumes(APPLICATION_JSON) - ListenableFuture thaw(@PathParam("fqdn") String fqdn) throws JobStillRunningException; -} diff --git a/providers/dynect/src/test/java/org/jclouds/dynect/v3/internal/BaseDynECTExpectTest.java b/providers/dynect/src/test/java/org/jclouds/dynect/v3/internal/BaseDynECTExpectTest.java index 9dd5fd0c87..ac28059049 100644 --- a/providers/dynect/src/test/java/org/jclouds/dynect/v3/internal/BaseDynECTExpectTest.java +++ b/providers/dynect/src/test/java/org/jclouds/dynect/v3/internal/BaseDynECTExpectTest.java @@ -22,13 +22,13 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static javax.ws.rs.core.Response.Status.NOT_FOUND; import static javax.ws.rs.core.Response.Status.OK; -import org.jclouds.dynect.v3.config.DynECTRestClientModule; +import org.jclouds.dynect.v3.config.DynECTHttpApiModule; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.http.config.SSLModule; import org.jclouds.io.Payload; import org.jclouds.io.Payloads; -import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.ConfiguresHttpApi; import org.jclouds.rest.internal.BaseRestApiExpectTest; import com.google.inject.Module; @@ -47,11 +47,11 @@ public class BaseDynECTExpectTest extends BaseRestApiExpectTest { @Override protected Module createModule() { - return new TestDynECTRestClientModule(); + return new TestDynECTHttpApiModule(); } - @ConfiguresRestClient - private static final class TestDynECTRestClientModule extends DynECTRestClientModule { + @ConfiguresHttpApi + private static final class TestDynECTHttpApiModule extends DynECTHttpApiModule { @Override protected void configure() { install(new SSLModule()); diff --git a/providers/hpcloud-compute/src/main/java/org/jclouds/hpcloud/compute/HPCloudComputeProviderMetadata.java b/providers/hpcloud-compute/src/main/java/org/jclouds/hpcloud/compute/HPCloudComputeProviderMetadata.java index 85010435b7..1a85c96c2b 100644 --- a/providers/hpcloud-compute/src/main/java/org/jclouds/hpcloud/compute/HPCloudComputeProviderMetadata.java +++ b/providers/hpcloud-compute/src/main/java/org/jclouds/hpcloud/compute/HPCloudComputeProviderMetadata.java @@ -29,6 +29,7 @@ import java.util.Properties; import org.jclouds.hpcloud.compute.config.HPCloudComputeServiceContextModule; 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.NovaApiMetadata; import org.jclouds.openstack.nova.v2_0.config.NovaParserModule; @@ -84,6 +85,7 @@ public class HPCloudComputeProviderMetadata extends BaseProviderMetadata { .endpointName("identity service url ending in /v2.0/") .defaultEndpoint("https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/") .defaultModules(ImmutableSet.>builder() + .add(MappedAuthenticationApiModule.class) .add(KeystoneAuthenticationModule.class) .add(ZoneModule.class) .add(NovaParserModule.class) diff --git a/providers/hpcloud-objectstorage/src/main/java/org/jclouds/hpcloud/objectstorage/HPCloudObjectStorageApiMetadata.java b/providers/hpcloud-objectstorage/src/main/java/org/jclouds/hpcloud/objectstorage/HPCloudObjectStorageApiMetadata.java index 4aa072e1e7..bc9f985e5c 100644 --- a/providers/hpcloud-objectstorage/src/main/java/org/jclouds/hpcloud/objectstorage/HPCloudObjectStorageApiMetadata.java +++ b/providers/hpcloud-objectstorage/src/main/java/org/jclouds/hpcloud/objectstorage/HPCloudObjectStorageApiMetadata.java @@ -18,7 +18,7 @@ */ package org.jclouds.hpcloud.objectstorage; -import static org.jclouds.rest.config.BinderUtils.bindHttpApi; +import static org.jclouds.rest.config.BinderUtils.bindSyncToAsyncHttpApi; import java.net.URI; import java.util.Properties; @@ -27,6 +27,7 @@ import org.jclouds.blobstore.BlobRequestSigner; import org.jclouds.hpcloud.objectstorage.blobstore.HPCloudObjectStorageBlobRequestSigner; import org.jclouds.hpcloud.objectstorage.blobstore.config.HPCloudObjectStorageBlobStoreContextModule; import org.jclouds.hpcloud.objectstorage.config.HPCloudObjectStorageRestClientModule; +import org.jclouds.openstack.keystone.v2_0.config.MappedAuthenticationApiModule; import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule; import org.jclouds.openstack.swift.SwiftKeystoneApiMetadata; import org.jclouds.openstack.swift.blobstore.config.TemporaryUrlExtensionModule; @@ -83,6 +84,7 @@ public class HPCloudObjectStorageApiMetadata extends SwiftKeystoneApiMetadata { .defaultProperties(HPCloudObjectStorageApiMetadata.defaultProperties()) .context(CONTEXT_TOKEN) .defaultModules(ImmutableSet.>builder() + .add(MappedAuthenticationApiModule.class) .add(KeystoneStorageEndpointModule.class) .add(RegionModule.class) .add(HPCloudObjectStorageRestClientModule.class) @@ -112,7 +114,7 @@ public class HPCloudObjectStorageApiMetadata extends SwiftKeystoneApiMetadata { } @Override protected void bindTemporaryUrlKeyApi() { - bindHttpApi(binder(), TemporaryUrlKeyApi.class, KeystoneTemporaryUrlKeyAsyncApi.class); + bindSyncToAsyncHttpApi(binder(), TemporaryUrlKeyApi.class, KeystoneTemporaryUrlKeyAsyncApi.class); } } } diff --git a/providers/hpcloud-objectstorage/src/test/java/org/jclouds/hpcloud/objectstorage/blobstore/HPCloudObjectStorageBlobSignerExpectTest.java b/providers/hpcloud-objectstorage/src/test/java/org/jclouds/hpcloud/objectstorage/blobstore/HPCloudObjectStorageBlobSignerExpectTest.java index 7dc156b82b..00a70e3252 100644 --- a/providers/hpcloud-objectstorage/src/test/java/org/jclouds/hpcloud/objectstorage/blobstore/HPCloudObjectStorageBlobSignerExpectTest.java +++ b/providers/hpcloud-objectstorage/src/test/java/org/jclouds/hpcloud/objectstorage/blobstore/HPCloudObjectStorageBlobSignerExpectTest.java @@ -30,6 +30,7 @@ import org.jclouds.hpcloud.objectstorage.blobstore.config.HPCloudObjectStorageBl import org.jclouds.hpcloud.objectstorage.config.HPCloudObjectStorageRestClientModule; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.keystone.v2_0.config.MappedAuthenticationApiModule; import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule; import org.jclouds.openstack.swift.config.SwiftRestClientModule.KeystoneStorageEndpointModule; import org.testng.annotations.Test; @@ -132,6 +133,7 @@ public class HPCloudObjectStorageBlobSignerExpectTest extends BaseBlobSignerExpe protected ApiMetadata createApiMetadata() { return new HPCloudObjectStorageApiMetadata().toBuilder() .defaultModules(ImmutableSet.>builder() + .add(MappedAuthenticationApiModule.class) .add(KeystoneStorageEndpointModule.class) .add(RegionModule.class) .add(HPCloudObjectStorageRestClientModule.class) diff --git a/providers/rackspace-cloudblockstorage-uk/src/main/java/org/jclouds/rackspace/cloudblockstorage/uk/CloudBlockStorageUKProviderMetadata.java b/providers/rackspace-cloudblockstorage-uk/src/main/java/org/jclouds/rackspace/cloudblockstorage/uk/CloudBlockStorageUKProviderMetadata.java index c23106734c..e2b50c504b 100644 --- a/providers/rackspace-cloudblockstorage-uk/src/main/java/org/jclouds/rackspace/cloudblockstorage/uk/CloudBlockStorageUKProviderMetadata.java +++ b/providers/rackspace-cloudblockstorage-uk/src/main/java/org/jclouds/rackspace/cloudblockstorage/uk/CloudBlockStorageUKProviderMetadata.java @@ -34,6 +34,7 @@ import org.jclouds.providers.ProviderMetadata; import org.jclouds.providers.internal.BaseProviderMetadata; 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.SyncToAsyncCloudIdentityAuthenticationApiModule; import com.google.common.collect.ImmutableSet; import com.google.inject.Module; @@ -82,6 +83,7 @@ public class CloudBlockStorageUKProviderMetadata extends BaseProviderMetadata { .endpointName("identity service url ending in /v2.0/") .documentation(URI.create("http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/overview.html")) .defaultModules(ImmutableSet.>builder() + .add(SyncToAsyncCloudIdentityAuthenticationApiModule.class) .add(CloudIdentityAuthenticationModule.class) .add(ZoneModule.class) .add(CinderParserModule.class) diff --git a/providers/rackspace-cloudblockstorage-us/src/main/java/org/jclouds/rackspace/cloudblockstorage/us/CloudBlockStorageUSProviderMetadata.java b/providers/rackspace-cloudblockstorage-us/src/main/java/org/jclouds/rackspace/cloudblockstorage/us/CloudBlockStorageUSProviderMetadata.java index 69fafc18a1..0c7174b599 100644 --- a/providers/rackspace-cloudblockstorage-us/src/main/java/org/jclouds/rackspace/cloudblockstorage/us/CloudBlockStorageUSProviderMetadata.java +++ b/providers/rackspace-cloudblockstorage-us/src/main/java/org/jclouds/rackspace/cloudblockstorage/us/CloudBlockStorageUSProviderMetadata.java @@ -34,6 +34,7 @@ import org.jclouds.providers.ProviderMetadata; import org.jclouds.providers.internal.BaseProviderMetadata; 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.SyncToAsyncCloudIdentityAuthenticationApiModule; import com.google.common.collect.ImmutableSet; import com.google.inject.Module; @@ -83,6 +84,7 @@ public class CloudBlockStorageUSProviderMetadata extends BaseProviderMetadata { .endpointName("identity service url ending in /v2.0/") .documentation(URI.create("http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/overview.html")) .defaultModules(ImmutableSet.>builder() + .add(SyncToAsyncCloudIdentityAuthenticationApiModule.class) .add(CloudIdentityAuthenticationModule.class) .add(ZoneModule.class) .add(CinderParserModule.class) diff --git a/providers/rackspace-cloudloadbalancers-uk/src/main/java/org/jclouds/rackspace/cloudloadbalancers/uk/CloudLoadBalancersUKProviderMetadata.java b/providers/rackspace-cloudloadbalancers-uk/src/main/java/org/jclouds/rackspace/cloudloadbalancers/uk/CloudLoadBalancersUKProviderMetadata.java index addb24e4d1..c3bdd2cf83 100644 --- a/providers/rackspace-cloudloadbalancers-uk/src/main/java/org/jclouds/rackspace/cloudloadbalancers/uk/CloudLoadBalancersUKProviderMetadata.java +++ b/providers/rackspace-cloudloadbalancers-uk/src/main/java/org/jclouds/rackspace/cloudloadbalancers/uk/CloudLoadBalancersUKProviderMetadata.java @@ -25,16 +25,9 @@ import static org.jclouds.location.reference.LocationConstants.PROPERTY_ZONES; import java.net.URI; import java.util.Properties; -import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.ZoneModule; import org.jclouds.providers.ProviderMetadata; import org.jclouds.providers.internal.BaseProviderMetadata; -import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule; import org.jclouds.rackspace.cloudloadbalancers.v1.CloudLoadBalancersApiMetadata; -import org.jclouds.rackspace.cloudloadbalancers.v1.config.CloudLoadBalancersRestClientModule; -import org.jclouds.rackspace.cloudloadbalancers.v1.loadbalancer.config.CloudLoadBalancersLoadBalancerContextModule; - -import com.google.common.collect.ImmutableSet; -import com.google.inject.Module; /** * Implementation of {@link org.jclouds.types.ProviderMetadata} for Rackspace Cloud LoadBalancers UK. @@ -72,18 +65,7 @@ public class CloudLoadBalancersUKProviderMetadata extends BaseProviderMetadata { id("rackspace-cloudloadbalancers-uk") .name("Rackspace Cloud Load Balancers UK") .apiMetadata(new CloudLoadBalancersApiMetadata().toBuilder() - .identityName("${userName}") - .credentialName("${apiKey}") - .version("1.0") .defaultEndpoint("https://lon.identity.api.rackspacecloud.com/v2.0/") - .endpointName("Identity service URL ending in /v2.0/") - .documentation(URI.create("http://docs.rackspace.com/loadbalancers/api/clb-devguide-latest/index.html")) - .defaultModules(ImmutableSet.>builder() - .add(CloudIdentityAuthenticationModule.class) - .add(ZoneModule.class) - .add(CloudLoadBalancersRestClientModule.class) - .add(CloudLoadBalancersLoadBalancerContextModule.class) - .build()) .build()) .homepage(URI.create("http://www.rackspace.co.uk/cloud-load-balancers/")) .console(URI.create("https://mycloud.rackspace.co.uk")) diff --git a/providers/rackspace-cloudloadbalancers-us/src/main/java/org/jclouds/rackspace/cloudloadbalancers/us/CloudLoadBalancersUSProviderMetadata.java b/providers/rackspace-cloudloadbalancers-us/src/main/java/org/jclouds/rackspace/cloudloadbalancers/us/CloudLoadBalancersUSProviderMetadata.java index 2dd9f626ab..adc0a47d15 100644 --- a/providers/rackspace-cloudloadbalancers-us/src/main/java/org/jclouds/rackspace/cloudloadbalancers/us/CloudLoadBalancersUSProviderMetadata.java +++ b/providers/rackspace-cloudloadbalancers-us/src/main/java/org/jclouds/rackspace/cloudloadbalancers/us/CloudLoadBalancersUSProviderMetadata.java @@ -25,16 +25,9 @@ import static org.jclouds.location.reference.LocationConstants.PROPERTY_ZONES; import java.net.URI; import java.util.Properties; -import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.ZoneModule; import org.jclouds.providers.ProviderMetadata; import org.jclouds.providers.internal.BaseProviderMetadata; -import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule; import org.jclouds.rackspace.cloudloadbalancers.v1.CloudLoadBalancersApiMetadata; -import org.jclouds.rackspace.cloudloadbalancers.v1.config.CloudLoadBalancersRestClientModule; -import org.jclouds.rackspace.cloudloadbalancers.v1.loadbalancer.config.CloudLoadBalancersLoadBalancerContextModule; - -import com.google.common.collect.ImmutableSet; -import com.google.inject.Module; /** * Implementation of {@link org.jclouds.types.ProviderMetadata} for Rackspace Cloud LoadBalancers US. @@ -74,18 +67,7 @@ public class CloudLoadBalancersUSProviderMetadata extends BaseProviderMetadata { id("rackspace-cloudloadbalancers-us") .name("Rackspace Cloud Load Balancers US") .apiMetadata(new CloudLoadBalancersApiMetadata().toBuilder() - .identityName("${userName}") - .credentialName("${apiKey}") - .version("1.0") .defaultEndpoint("https://identity.api.rackspacecloud.com/v2.0/") - .endpointName("Identity service URL ending in /v2.0/") - .documentation(URI.create("http://docs.rackspace.com/loadbalancers/api/clb-devguide-latest/index.html")) - .defaultModules(ImmutableSet.>builder() - .add(CloudIdentityAuthenticationModule.class) - .add(ZoneModule.class) - .add(CloudLoadBalancersRestClientModule.class) - .add(CloudLoadBalancersLoadBalancerContextModule.class) - .build()) .build()) .homepage(URI.create("http://www.rackspace.com/cloud/public/loadbalancers/")) .console(URI.create("https://mycloud.rackspace.com")) diff --git a/providers/rackspace-cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/uk/CloudServersUKProviderMetadata.java b/providers/rackspace-cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/uk/CloudServersUKProviderMetadata.java index 9202e9c4fd..b50c8ee733 100644 --- a/providers/rackspace-cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/uk/CloudServersUKProviderMetadata.java +++ b/providers/rackspace-cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/uk/CloudServersUKProviderMetadata.java @@ -34,6 +34,7 @@ import org.jclouds.providers.ProviderMetadata; import org.jclouds.providers.internal.BaseProviderMetadata; 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.SyncToAsyncCloudIdentityAuthenticationApiModule; import org.jclouds.rackspace.cloudservers.uk.config.CloudServersUKComputeServiceContextModule; import com.google.common.collect.ImmutableSet; @@ -84,6 +85,7 @@ public class CloudServersUKProviderMetadata extends BaseProviderMetadata { .endpointName("identity service url ending in /v2.0/") .documentation(URI.create("http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_preface.html#webhelp-currentid")) .defaultModules(ImmutableSet.>builder() + .add(SyncToAsyncCloudIdentityAuthenticationApiModule.class) .add(CloudIdentityAuthenticationModule.class) .add(ZoneModule.class) .add(NovaParserModule.class) diff --git a/providers/rackspace-cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/us/CloudServersUSProviderMetadata.java b/providers/rackspace-cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/us/CloudServersUSProviderMetadata.java index 1480a1f390..dae907c415 100644 --- a/providers/rackspace-cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/us/CloudServersUSProviderMetadata.java +++ b/providers/rackspace-cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/us/CloudServersUSProviderMetadata.java @@ -34,6 +34,7 @@ import org.jclouds.providers.ProviderMetadata; import org.jclouds.providers.internal.BaseProviderMetadata; 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.SyncToAsyncCloudIdentityAuthenticationApiModule; import org.jclouds.rackspace.cloudservers.us.config.CloudServersUSComputeServiceContextModule; import com.google.common.collect.ImmutableSet; @@ -85,6 +86,7 @@ public class CloudServersUSProviderMetadata extends BaseProviderMetadata { .endpointName("identity service url ending in /v2.0/") .documentation(URI.create("http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/index.html")) .defaultModules(ImmutableSet.>builder() + .add(SyncToAsyncCloudIdentityAuthenticationApiModule.class) .add(CloudIdentityAuthenticationModule.class) .add(ZoneModule.class) .add(NovaParserModule.class) diff --git a/providers/trystack-nova/src/main/java/org/jclouds/trystack/nova/TryStackNovaProviderMetadata.java b/providers/trystack-nova/src/main/java/org/jclouds/trystack/nova/TryStackNovaProviderMetadata.java index 72205dd3c5..16299e5890 100644 --- a/providers/trystack-nova/src/main/java/org/jclouds/trystack/nova/TryStackNovaProviderMetadata.java +++ b/providers/trystack-nova/src/main/java/org/jclouds/trystack/nova/TryStackNovaProviderMetadata.java @@ -26,6 +26,7 @@ import java.util.Properties; 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.nova.v2_0.NovaApiMetadata; import org.jclouds.openstack.nova.v2_0.config.NovaParserModule; import org.jclouds.openstack.nova.v2_0.config.NovaRestClientModule; @@ -75,6 +76,7 @@ public class TryStackNovaProviderMetadata extends BaseProviderMetadata { .apiMetadata( new NovaApiMetadata().toBuilder() .defaultModules(ImmutableSet.>builder() + .add(MappedAuthenticationApiModule.class) .add(KeystoneAuthenticationModule.class) .add(ZoneModule.class) .add(NovaParserModule.class) diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApi.java index 4109cad821..827038d621 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApi.java @@ -20,27 +20,41 @@ package org.jclouds.ultradns.ws; import java.io.Closeable; +import javax.inject.Named; +import javax.ws.rs.POST; + import org.jclouds.rest.annotations.Delegate; +import org.jclouds.rest.annotations.Payload; import org.jclouds.rest.annotations.PayloadParam; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.ultradns.ws.domain.Account; import org.jclouds.ultradns.ws.features.ResourceRecordApi; import org.jclouds.ultradns.ws.features.RoundRobinPoolApi; import org.jclouds.ultradns.ws.features.TaskApi; import org.jclouds.ultradns.ws.features.TrafficControllerPoolApi; import org.jclouds.ultradns.ws.features.ZoneApi; +import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; +import org.jclouds.ultradns.ws.xml.AccountHandler; /** * Provides access to Neustar UltraDNS via the SOAP API *

    * - * @see UltraDNSWSAsyncApi * @see * @author Adrian Cole */ +@RequestFilters(SOAPWrapWithPasswordAuth.class) +@VirtualHost public interface UltraDNSWSApi extends Closeable { /** * Returns the account of the current user. */ + @Named("getAccountsListOfUser") + @POST + @XMLResponseParser(AccountHandler.class) + @Payload("") Account getCurrentAccount(); /** diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApiMetadata.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApiMetadata.java index de7127e3a7..f0131fd819 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApiMetadata.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSApiMetadata.java @@ -22,38 +22,37 @@ import java.net.URI; import java.util.Properties; import org.jclouds.apis.ApiMetadata; -import org.jclouds.rest.internal.BaseRestApiMetadata; -import org.jclouds.ultradns.ws.config.UltraDNSWSRestClientModule; +import org.jclouds.rest.internal.BaseHttpApiMetadata; +import org.jclouds.ultradns.ws.config.UltraDNSWSHttpApiModule; /** * Implementation of {@link ApiMetadata} for Neustar's UltraDNSWS api. * * @author Adrian Cole */ -public class UltraDNSWSApiMetadata extends BaseRestApiMetadata { +public class UltraDNSWSApiMetadata extends BaseHttpApiMetadata { @Override public Builder toBuilder() { - return new Builder(getApi(), getAsyncApi()).fromApiMetadata(this); + return new Builder().fromApiMetadata(this); } public UltraDNSWSApiMetadata() { - this(new Builder(UltraDNSWSApi.class, UltraDNSWSAsyncApi.class)); + this(new Builder()); } protected UltraDNSWSApiMetadata(Builder builder) { - super(Builder.class.cast(builder)); + super(builder); } public static Properties defaultProperties() { - Properties properties = BaseRestApiMetadata.defaultProperties(); + Properties properties = BaseHttpApiMetadata.defaultProperties(); return properties; } - public static class Builder extends BaseRestApiMetadata.Builder { + public static class Builder extends BaseHttpApiMetadata.Builder { - protected Builder(Class api, Class asyncApi) { - super(api, asyncApi); + protected Builder() { id("ultradns-ws") .name("Neustar UltraDNS WS Api") .identityName("Username") @@ -62,7 +61,7 @@ public class UltraDNSWSApiMetadata extends BaseRestApiMetadata { .documentation(URI.create("https://portal.ultradns.com/static/docs/NUS_API_XML_SOAP.pdf")) .defaultEndpoint("https://ultra-api.ultradns.com:8443/UltraDNS_WS/v01") .defaultProperties(UltraDNSWSApiMetadata.defaultProperties()) - .defaultModule(UltraDNSWSRestClientModule.class); + .defaultModule(UltraDNSWSHttpApiModule.class); } @Override diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSAsyncApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSAsyncApi.java deleted file mode 100644 index fea3f8d684..0000000000 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/UltraDNSWSAsyncApi.java +++ /dev/null @@ -1,105 +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.ultradns.ws; - -import java.io.Closeable; - -import javax.inject.Named; -import javax.ws.rs.POST; - -import org.jclouds.rest.annotations.Delegate; -import org.jclouds.rest.annotations.Payload; -import org.jclouds.rest.annotations.PayloadParam; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.VirtualHost; -import org.jclouds.rest.annotations.XMLResponseParser; -import org.jclouds.ultradns.ws.domain.Account; -import org.jclouds.ultradns.ws.features.ResourceRecordAsyncApi; -import org.jclouds.ultradns.ws.features.RoundRobinPoolAsyncApi; -import org.jclouds.ultradns.ws.features.TaskAsyncApi; -import org.jclouds.ultradns.ws.features.TrafficControllerPoolAsyncApi; -import org.jclouds.ultradns.ws.features.ZoneAsyncApi; -import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; -import org.jclouds.ultradns.ws.xml.AccountHandler; - -import com.google.common.util.concurrent.ListenableFuture; - -/** - * Provides access to Neustar UltraDNS via the SOAP API - *

    - * - * @see - * @see - * @author Adrian Cole - * @deprecated please use {@code org.jclouds.ContextBuilder#buildApi(UltraDNSWSApi.class)} as - * {@link UltraDNSWSAsyncApi} interface will be removed in jclouds 1.7. - */ -@Deprecated -@RequestFilters(SOAPWrapWithPasswordAuth.class) -@VirtualHost -public interface UltraDNSWSAsyncApi extends Closeable { - - /** - * @see UltraDNSWSApi#getCurrentAccount() - */ - @Named("getAccountsListOfUser") - @POST - @XMLResponseParser(AccountHandler.class) - @Payload("") - ListenableFuture getCurrentAccount(); - - /** - * Provides asynchronous access to Zone features. - */ - @Delegate - ZoneAsyncApi getZoneApi(); - - /** - * Provides asynchronous access to Resource Record features. - * - * @param zoneName - * zoneName including a trailing dot - */ - @Delegate - ResourceRecordAsyncApi getResourceRecordApiForZone(@PayloadParam("zoneName") String zoneName); - - /** - * Provides asynchronous access to Round Robin Pool features. - * - * @param zoneName - * zoneName including a trailing dot - */ - @Delegate - RoundRobinPoolAsyncApi getRoundRobinPoolApiForZone(@PayloadParam("zoneName") String zoneName); - - /** - * Provides asynchronous access to Traffic Controller Pool features. - * - * @param zoneName - * zoneName including a trailing dot - */ - @Delegate - TrafficControllerPoolAsyncApi getTrafficControllerPoolApiForZone(@PayloadParam("zoneName") String zoneName); - - /** - * Provides asynchronous access to Task features. - */ - @Delegate - TaskAsyncApi getTaskApi(); -} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/config/UltraDNSWSRestClientModule.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/config/UltraDNSWSHttpApiModule.java similarity index 55% rename from providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/config/UltraDNSWSRestClientModule.java rename to providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/config/UltraDNSWSHttpApiModule.java index a5aa13b662..9c23387cd1 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/config/UltraDNSWSRestClientModule.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/config/UltraDNSWSHttpApiModule.java @@ -18,48 +18,24 @@ */ package org.jclouds.ultradns.ws.config; -import java.util.Map; - 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.ConfiguresRestClient; -import org.jclouds.rest.config.RestClientModule; +import org.jclouds.rest.ConfiguresHttpApi; +import org.jclouds.rest.config.HttpApiModule; import org.jclouds.ultradns.ws.UltraDNSWSApi; -import org.jclouds.ultradns.ws.UltraDNSWSAsyncApi; -import org.jclouds.ultradns.ws.features.ResourceRecordApi; -import org.jclouds.ultradns.ws.features.ResourceRecordAsyncApi; -import org.jclouds.ultradns.ws.features.RoundRobinPoolApi; -import org.jclouds.ultradns.ws.features.RoundRobinPoolAsyncApi; -import org.jclouds.ultradns.ws.features.TaskApi; -import org.jclouds.ultradns.ws.features.TaskAsyncApi; -import org.jclouds.ultradns.ws.features.TrafficControllerPoolApi; -import org.jclouds.ultradns.ws.features.TrafficControllerPoolAsyncApi; -import org.jclouds.ultradns.ws.features.ZoneApi; -import org.jclouds.ultradns.ws.features.ZoneAsyncApi; import org.jclouds.ultradns.ws.handlers.UltraDNSWSErrorHandler; -import com.google.common.collect.ImmutableMap; - /** * Configures the UltraDNSWS connection. * * @author Adrian Cole */ -@ConfiguresRestClient -public class UltraDNSWSRestClientModule extends RestClientModule { - - public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder() - .put(ZoneApi.class, ZoneAsyncApi.class) - .put(ResourceRecordApi.class, ResourceRecordAsyncApi.class) - .put(RoundRobinPoolApi.class, RoundRobinPoolAsyncApi.class) - .put(TrafficControllerPoolApi.class, TrafficControllerPoolAsyncApi.class) - .put(TaskApi.class, TaskAsyncApi.class).build(); - - public UltraDNSWSRestClientModule() { - super(DELEGATE_MAP); +@ConfiguresHttpApi +public class UltraDNSWSHttpApiModule extends HttpApiModule { + public UltraDNSWSHttpApiModule() { } @Override diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/PoolRecordSpec.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/PoolRecordSpec.java index f9d3b8a385..02f14d608c 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/PoolRecordSpec.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/PoolRecordSpec.java @@ -47,13 +47,13 @@ public final class PoolRecordSpec { this.probingEnabled = probingEnabled; this.allFailEnabled = allFailEnabled; this.weight = weight; - checkArgument(weight >= 0, "weight of %s must be unsigned", description); + checkArgument(weight >= 0, "weight of %s must be >= 0", description); this.failOverDelay = failOverDelay; - checkArgument(failOverDelay >= 0, "failOverDelay of %s must be unsigned", description); + checkArgument(failOverDelay >= 0, "failOverDelay of %s must be >= 0", description); this.threshold = threshold; - checkArgument(threshold >= 0, "threshold of %s must be unsigned", description); + checkArgument(threshold >= 0, "threshold of %s must be >= 0", description); this.ttl = ttl; - checkArgument(ttl >= 0, "ttl of %s must be unsigned", description); + checkArgument(ttl >= 0, "ttl of %s must be >= 0", description); } /** @@ -114,8 +114,8 @@ public final class PoolRecordSpec { @Override public int hashCode() { - return Objects - .hashCode(description, state, probingEnabled, allFailEnabled, weight, failOverDelay, threshold, ttl); + return Objects.hashCode(description, state, probingEnabled, allFailEnabled, weight, failOverDelay, threshold, + ttl); } @Override diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ResourceRecord.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ResourceRecord.java index 3ade4b95b7..08dc6738c2 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ResourceRecord.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ResourceRecord.java @@ -42,9 +42,9 @@ public class ResourceRecord { private ResourceRecord(String dName, int type, int ttl, List infoValues) { this.dName = checkNotNull(dName, "dName"); - checkArgument(type >= 0, "type of %s must be unsigned", dName); + checkArgument(type >= 0, "type of %s must be >= 0", dName); this.type = type; - checkArgument(ttl >= 0, "ttl of %s must be unsigned", dName); + checkArgument(ttl >= 0, "ttl of %s must be >= 0", dName); this.ttl = ttl; this.infoValues = checkNotNull(infoValues, "infoValues of %s", dName); } diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/TrafficControllerPoolRecord.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/TrafficControllerPoolRecord.java index 061aaf6ab7..1a05fced1d 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/TrafficControllerPoolRecord.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/TrafficControllerPoolRecord.java @@ -46,9 +46,9 @@ public final class TrafficControllerPoolRecord { this.id = checkNotNull(id, "id"); this.poolId = checkNotNull(poolId, "poolId for %s", id); this.pointsTo = checkNotNull(pointsTo, "pointsTo for %s", poolId); - checkArgument(weight >= 0, "weight of %s must be unsigned", id); + checkArgument(weight >= 0, "weight of %s must be >= 0", id); this.weight = weight; - checkArgument(priority >= 0, "priority of %s must be unsigned", id); + checkArgument(priority >= 0, "priority of %s must be >= 0", id); this.priority = priority; this.type = checkNotNull(type, "type for %s", poolId); this.forceAnswer = checkNotNull(forceAnswer, "forceAnswer for %s", poolId); diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/UpdatePoolRecord.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/UpdatePoolRecord.java index a7883b4e30..b8117cd9be 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/UpdatePoolRecord.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/UpdatePoolRecord.java @@ -54,13 +54,13 @@ public final class UpdatePoolRecord { this.mode = checkNotNull(mode, "mode for %s", pointsTo); this.priority = priority; this.weight = weight; - checkArgument(weight >= 0, "weight of %s must be unsigned", pointsTo); + checkArgument(weight >= 0, "weight of %s must be >= 0", pointsTo); this.failOverDelay = failOverDelay; - checkArgument(failOverDelay >= 0, "failOverDelay of %s must be unsigned", pointsTo); + checkArgument(failOverDelay >= 0, "failOverDelay of %s must be >= 0", pointsTo); this.threshold = threshold; - checkArgument(threshold >= 0, "threshold of %s must be unsigned", pointsTo); + checkArgument(threshold >= 0, "threshold of %s must be >= 0", pointsTo); this.ttl = ttl; - checkArgument(ttl >= 0, "ttl of %s must be unsigned", pointsTo); + checkArgument(ttl >= 0, "ttl of %s must be >= 0", pointsTo); } /** diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/Zone.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/Zone.java index 45b6e83686..60370f6625 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/Zone.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/Zone.java @@ -43,7 +43,7 @@ public final class Zone { DNSSECStatus dnssecStatus, Optional primarySrc) { this.id = checkNotNull(id, "id"); this.name = checkNotNull(name, "name for %s", id); - checkArgument(typeCode >= 0, "typeCode of %s must be unsigned", id); + checkArgument(typeCode >= 0, "typeCode of %s must be >= 0", id); this.typeCode = typeCode; this.type = checkNotNull(type, "type for %s", name); this.accountId = checkNotNull(accountId, "accountId for %s", name); diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ZoneProperties.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ZoneProperties.java index 014a7f801b..e2cd0472d4 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ZoneProperties.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/domain/ZoneProperties.java @@ -41,7 +41,7 @@ public final class ZoneProperties { private ZoneProperties(String name, Type type, int typeCode, Date modified, int resourceRecordCount) { this.name = checkNotNull(name, "name"); - checkArgument(typeCode >= 0, "typeCode of %s must be unsigned", name); + checkArgument(typeCode >= 0, "typeCode of %s must be >= 0", name); this.typeCode = typeCode; this.type = checkNotNull(type, "type for %s", name); this.modified = checkNotNull(modified, "modified for %s", name); diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java index f81ef402bb..77c309bca9 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordApi.java @@ -18,17 +18,35 @@ */ package org.jclouds.ultradns.ws.features; +import javax.inject.Named; +import javax.ws.rs.POST; + +import org.jclouds.Fallbacks.VoidOnNotFoundOr404; import org.jclouds.rest.ResourceNotFoundException; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.Payload; +import org.jclouds.rest.annotations.PayloadParam; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; +import org.jclouds.ultradns.ws.binders.ZoneAndResourceRecordToXML; import org.jclouds.ultradns.ws.domain.ResourceRecord; import org.jclouds.ultradns.ws.domain.ResourceRecordMetadata; +import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; +import org.jclouds.ultradns.ws.xml.ElementTextHandler; +import org.jclouds.ultradns.ws.xml.ResourceRecordListHandler; import com.google.common.collect.FluentIterable; /** - * @see ResourceRecordAsyncApi + * @see + * @see * @author Adrian Cole */ +@RequestFilters(SOAPWrapWithPasswordAuth.class) +@VirtualHost public interface ResourceRecordApi { /** @@ -40,7 +58,12 @@ public interface ResourceRecordApi { * @throws ResourceAlreadyExistsException * if a record already exists with the same attrs */ - String create(ResourceRecord toCreate) throws ResourceAlreadyExistsException; + @Named("createResourceRecord") + @POST + @XMLResponseParser(ElementTextHandler.Guid.class) + @MapBinder(ZoneAndResourceRecordToXML.class) + String create(@PayloadParam("resourceRecord") ResourceRecord toCreate) + throws ResourceAlreadyExistsException; /** * updates an existing resource record in the zone. @@ -53,7 +76,11 @@ public interface ResourceRecordApi { * @throws ResourceNotFoundException * if the guid doesn't exist */ - void update(String guid, ResourceRecord updated) throws ResourceNotFoundException; + @Named("updateResourceRecord") + @POST + @MapBinder(ZoneAndResourceRecordToXML.class) + void update(@PayloadParam("guid") String guid, + @PayloadParam("resourceRecord") ResourceRecord toCreate) throws ResourceNotFoundException; /** * Returns all the specified record types in the zone. @@ -61,6 +88,10 @@ public interface ResourceRecordApi { * @throws ResourceNotFoundException * if the zone doesn't exist */ + @Named("getResourceRecordsOfZone") + @POST + @XMLResponseParser(ResourceRecordListHandler.class) + @Payload("{zoneName}0") FluentIterable list() throws ResourceNotFoundException; /** @@ -72,7 +103,12 @@ public interface ResourceRecordApi { * @throws ResourceNotFoundException * if the zone doesn't exist */ - FluentIterable listByName(String hostName) throws ResourceNotFoundException; + @Named("getResourceRecordsOfDNameByType") + @POST + @XMLResponseParser(ResourceRecordListHandler.class) + @Payload("{zoneName}{hostName}0") + FluentIterable listByName(@PayloadParam("hostName") String hostName) + throws ResourceNotFoundException; /** * Returns all the specified record types in the zone with the fully @@ -86,7 +122,12 @@ public interface ResourceRecordApi { * @throws ResourceNotFoundException * if the zone doesn't exist */ - FluentIterable listByNameAndType(String hostName, int rrType) + @Named("getResourceRecordsOfDNameByType") + @POST + @XMLResponseParser(ResourceRecordListHandler.class) + @Payload("{zoneName}{hostName}{rrType}") + FluentIterable listByNameAndType( + @PayloadParam("hostName") String hostName, @PayloadParam("rrType") int rrType) throws ResourceNotFoundException; /** @@ -96,5 +137,9 @@ public interface ResourceRecordApi { * the global unique identifier for the resource record {@see * ResourceRecordMetadata#getGuid()} */ - void delete(String guid); + @Named("deleteResourceRecord") + @POST + @Payload("{guid}") + @Fallback(VoidOnNotFoundOr404.class) + void delete(@PayloadParam("guid") String guid); } diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordAsyncApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordAsyncApi.java deleted file mode 100644 index d8fab3688e..0000000000 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ResourceRecordAsyncApi.java +++ /dev/null @@ -1,111 +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.ultradns.ws.features; - -import javax.inject.Named; -import javax.ws.rs.POST; - -import org.jclouds.Fallbacks.VoidOnNotFoundOr404; -import org.jclouds.rest.ResourceNotFoundException; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.Payload; -import org.jclouds.rest.annotations.PayloadParam; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.VirtualHost; -import org.jclouds.rest.annotations.XMLResponseParser; -import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; -import org.jclouds.ultradns.ws.binders.ZoneAndResourceRecordToXML; -import org.jclouds.ultradns.ws.domain.ResourceRecord; -import org.jclouds.ultradns.ws.domain.ResourceRecordMetadata; -import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; -import org.jclouds.ultradns.ws.xml.TextHandler; -import org.jclouds.ultradns.ws.xml.ResourceRecordListHandler; - -import com.google.common.collect.FluentIterable; -import com.google.common.util.concurrent.ListenableFuture; - -/** - * @see ResourceRecordApi - * @see - * @see - * @author Adrian Cole - */ -@RequestFilters(SOAPWrapWithPasswordAuth.class) -@VirtualHost -public interface ResourceRecordAsyncApi { - - /** - * @see ResourceRecordApi#create(ResourceRecordMetadata) - */ - @Named("createResourceRecord") - @POST - @XMLResponseParser(TextHandler.Guid.class) - @MapBinder(ZoneAndResourceRecordToXML.class) - ListenableFuture create(@PayloadParam("resourceRecord") ResourceRecord toCreate) - throws ResourceAlreadyExistsException; - - /** - * @see ResourceRecordApi#update(String guid, BasicResourceRecord) - */ - @Named("updateResourceRecord") - @POST - @MapBinder(ZoneAndResourceRecordToXML.class) - ListenableFuture update(@PayloadParam("guid") String guid, - @PayloadParam("resourceRecord") ResourceRecord toCreate) throws ResourceNotFoundException; - - /** - * @see ResourceRecordApi#list() - */ - @Named("getResourceRecordsOfZone") - @POST - @XMLResponseParser(ResourceRecordListHandler.class) - @Payload("{zoneName}0") - ListenableFuture> list() throws ResourceNotFoundException; - - /** - * @see ResourceRecordApi#listByName(String) - */ - @Named("getResourceRecordsOfDNameByType") - @POST - @XMLResponseParser(ResourceRecordListHandler.class) - @Payload("{zoneName}{hostName}0") - ListenableFuture> listByName(@PayloadParam("hostName") String hostName) - throws ResourceNotFoundException; - - /** - * @see ResourceRecordApi#listByNameAndType(String, int) - */ - @Named("getResourceRecordsOfDNameByType") - @POST - @XMLResponseParser(ResourceRecordListHandler.class) - @Payload("{zoneName}{hostName}{rrType}") - ListenableFuture> listByNameAndType( - @PayloadParam("hostName") String hostName, @PayloadParam("rrType") int rrType) - throws ResourceNotFoundException; - - /** - * @see ResourceRecordApi#delete(String) - */ - @Named("deleteResourceRecord") - @POST - @Payload("{guid}") - @Fallback(VoidOnNotFoundOr404.class) - ListenableFuture delete(@PayloadParam("guid") String guid); -} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java index 9c4eb87f18..80c198499a 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApi.java @@ -18,19 +18,62 @@ */ package org.jclouds.ultradns.ws.features; +import javax.inject.Named; +import javax.ws.rs.POST; + +import org.jclouds.Fallbacks.VoidOnNotFoundOr404; import org.jclouds.rest.ResourceNotFoundException; +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.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; import org.jclouds.ultradns.ws.domain.ResourceRecord; import org.jclouds.ultradns.ws.domain.ResourceRecordMetadata; import org.jclouds.ultradns.ws.domain.RoundRobinPool; +import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; +import org.jclouds.ultradns.ws.xml.ElementTextHandler; +import org.jclouds.ultradns.ws.xml.ResourceRecordListHandler; +import org.jclouds.ultradns.ws.xml.RoundRobinPoolListHandler; import com.google.common.collect.FluentIterable; /** - * @see RoundRobinPoolAsyncApi + * @see + * @see * @author Adrian Cole */ +@RequestFilters(SOAPWrapWithPasswordAuth.class) +@VirtualHost public interface RoundRobinPoolApi { + + /** + * Returns all round robin pools in the zone. + * + * @throws ResourceNotFoundException + * if the zone doesn't exist + */ + @Named("getLoadBalancingPoolsByZone") + @POST + @XMLResponseParser(RoundRobinPoolListHandler.class) + @Payload("{zoneName}RR") + FluentIterable list() throws ResourceNotFoundException; + + /** + * Returns all records in the round robin pool. + * + * @throws ResourceNotFoundException + * if the pool doesn't exist + */ + @Named("getRRPoolRecords") + @POST + @XMLResponseParser(ResourceRecordListHandler.class) + @Payload("{poolId}") + FluentIterable listRecords(@PayloadParam("poolId") String poolId) + throws ResourceNotFoundException; + /** * creates a round robin pool for {@code A} (ipv4) records * @@ -43,7 +86,12 @@ public interface RoundRobinPoolApi { * @throws ResourceAlreadyExistsException * if a pool already exists with the same attrs */ - String createAPoolForHostname(String name, String hostname) throws ResourceAlreadyExistsException; + @Named("addRRLBPool") + @POST + @XMLResponseParser(ElementTextHandler.RRPoolID.class) + @Payload("{zoneName}{hostName}{description}1") + String createAPoolForHostname(@PayloadParam("description") String name, + @PayloadParam("hostName") String hostname) throws ResourceAlreadyExistsException; /** * adds a new {@code A} record to the pool @@ -58,37 +106,12 @@ public interface RoundRobinPoolApi { * @throws ResourceAlreadyExistsException * if a record already exists with the same attrs */ - String addARecordWithAddressAndTTL(String lbPoolID, String ipv4Address, int ttl) - throws ResourceAlreadyExistsException; - - /** - * creates a round robin pool for {@code AAAA} (ipv6) records - * - * @param name - * {@link RoundRobinPool#getName() name} of the RR pool - * @param hostname - * {@link RoundRobinPool#getDName() hostname} {ex. - * www.jclouds.org.} - * @return the {@code guid} of the new record - * @throws ResourceAlreadyExistsException - * if a pool already exists with the same attrs - */ - String createAAAAPoolForHostname(String name, String hostname) throws ResourceAlreadyExistsException; - - /** - * adds a new {@code AAAA} record to the pool - * - * @param lbPoolID - * the pool to add the record to. - * @param ipv6Address - * the ipv6 address - * @param ttl - * the {@link ResourceRecord#getTTL ttl} of the record - * @return the {@code guid} of the new record - * @throws ResourceAlreadyExistsException - * if a record already exists with the same attrs - */ - String addAAAARecordWithAddressAndTTL(String lbPoolID, String ipv6Address, int ttl) + @Named("addRecordToRRPool") + @POST + @XMLResponseParser(ElementTextHandler.Guid.class) + @Payload("") + String addARecordWithAddressAndTTL(@PayloadParam("lbPoolID") String lbPoolID, + @PayloadParam("address") String ipv4Address, @PayloadParam("ttl") int ttl) throws ResourceAlreadyExistsException; /** @@ -107,24 +130,12 @@ public interface RoundRobinPoolApi { * @throws ResourceNotFoundException * if the guid doesn't exist */ - void updateRecordWithAddressAndTTL(String lbPoolID, String guid, String address, int ttl) - throws ResourceNotFoundException; - - /** - * Returns all round robin pools in the zone. - * - * @throws ResourceNotFoundException - * if the zone doesn't exist - */ - FluentIterable list() throws ResourceNotFoundException; - - /** - * Returns all records in the round robin pool. - * - * @throws ResourceNotFoundException - * if the pool doesn't exist - */ - FluentIterable listRecords(String poolId) throws ResourceNotFoundException; + @Named("updateRecordOfRRPool") + @POST + @Payload("") + void updateRecordWithAddressAndTTL(@PayloadParam("lbPoolID") String lbPoolID, + @PayloadParam("guid") String guid, @PayloadParam("address") String ipv4Address, + @PayloadParam("ttl") int ttl) throws ResourceNotFoundException; /** * deletes a specific pooled resource record @@ -133,7 +144,51 @@ public interface RoundRobinPoolApi { * the global unique identifier for the resource record {@see * ResourceRecordMetadata#getGuid()} */ - void deleteRecord(String guid); + @Named("deleteRecordOfRRPool") + @POST + @Payload("{guid}") + @Fallback(VoidOnNotFoundOr404.class) + void deleteRecord(@PayloadParam("guid") String guid); + + /** + * creates a round robin pool for {@code AAAA} (ipv6) records + * + * @param name + * {@link RoundRobinPool#getName() name} of the RR pool + * @param hostname + * {@link RoundRobinPool#getDName() hostname} {ex. + * www.jclouds.org.} + * @return the {@code guid} of the new record + * @throws ResourceAlreadyExistsException + * if a pool already exists with the same attrs + */ + @Named("addRRLBPool") + @POST + @XMLResponseParser(ElementTextHandler.RRPoolID.class) + @Payload("{zoneName}{hostName}{description}28") + String createAAAAPoolForHostname(@PayloadParam("description") String name, + @PayloadParam("hostName") String hostname) throws ResourceAlreadyExistsException; + + /** + * adds a new {@code AAAA} record to the pool + * + * @param lbPoolID + * the pool to add the record to. + * @param ipv6Address + * the ipv6 address + * @param ttl + * the {@link ResourceRecord#getTTL ttl} of the record + * @return the {@code guid} of the new record + * @throws ResourceAlreadyExistsException + * if a record already exists with the same attrs + */ + @Named("addRecordToRRPool") + @POST + @XMLResponseParser(ElementTextHandler.Guid.class) + @Payload("") + String addAAAARecordWithAddressAndTTL(@PayloadParam("lbPoolID") String lbPoolID, + @PayloadParam("address") String ipv6Address, @PayloadParam("ttl") int ttl) + throws ResourceAlreadyExistsException; /** * removes a pool and all its records and probes @@ -141,5 +196,9 @@ public interface RoundRobinPoolApi { * @param id * the {@link RoundRobinPool#getId() id} */ - void delete(String id); + @Named("deleteLBPool") + @POST + @Payload("{lbPoolID}Yes") + @Fallback(VoidOnNotFoundOr404.class) + void delete(@PayloadParam("lbPoolID") String id); } diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolAsyncApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolAsyncApi.java deleted file mode 100644 index ab27999f81..0000000000 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/RoundRobinPoolAsyncApi.java +++ /dev/null @@ -1,141 +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.ultradns.ws.features; - -import javax.inject.Named; -import javax.ws.rs.POST; - -import org.jclouds.Fallbacks.VoidOnNotFoundOr404; -import org.jclouds.rest.ResourceNotFoundException; -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.VirtualHost; -import org.jclouds.rest.annotations.XMLResponseParser; -import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; -import org.jclouds.ultradns.ws.domain.ResourceRecord; -import org.jclouds.ultradns.ws.domain.RoundRobinPool; -import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; -import org.jclouds.ultradns.ws.xml.TextHandler; -import org.jclouds.ultradns.ws.xml.ResourceRecordListHandler; -import org.jclouds.ultradns.ws.xml.RoundRobinPoolListHandler; - -import com.google.common.collect.FluentIterable; -import com.google.common.util.concurrent.ListenableFuture; - -/** - * @see RoundRobinPoolApi - * @see - * @see - * @author Adrian Cole - */ -@RequestFilters(SOAPWrapWithPasswordAuth.class) -@VirtualHost -public interface RoundRobinPoolAsyncApi { - - /** - * @see RoundRobinPoolApi#list() - */ - @Named("getLoadBalancingPoolsByZone") - @POST - @XMLResponseParser(RoundRobinPoolListHandler.class) - @Payload("{zoneName}RR") - ListenableFuture> list() throws ResourceNotFoundException; - - /** - * @see RoundRobinPoolApi#listRecords(String) - */ - @Named("getRRPoolRecords") - @POST - @XMLResponseParser(ResourceRecordListHandler.class) - @Payload("{poolId}") - ListenableFuture> listRecords(@PayloadParam("poolId") String poolId) - throws ResourceNotFoundException; - - /** - * @see RoundRobinPoolApi#createAPoolForHostname - */ - @Named("addRRLBPool") - @POST - @XMLResponseParser(TextHandler.RRPoolID.class) - @Payload("{zoneName}{hostName}{description}1") - ListenableFuture createAPoolForHostname(@PayloadParam("description") String name, - @PayloadParam("hostName") String hostname) throws ResourceAlreadyExistsException; - - /** - * @see RoundRobinPoolApi#addARecordWithAddressAndTTL - */ - @Named("addRecordToRRPool") - @POST - @XMLResponseParser(TextHandler.Guid.class) - @Payload("") - ListenableFuture addARecordWithAddressAndTTL(@PayloadParam("lbPoolID") String lbPoolID, - @PayloadParam("address") String ipv4Address, @PayloadParam("ttl") int ttl) - throws ResourceAlreadyExistsException; - - /** - * @see RoundRobinPoolApi#updateRecordWithAddressAndTTL - */ - @Named("updateRecordOfRRPool") - @POST - @Payload("") - ListenableFuture updateRecordWithAddressAndTTL(@PayloadParam("lbPoolID") String lbPoolID, - @PayloadParam("guid") String guid, @PayloadParam("address") String ipv4Address, - @PayloadParam("ttl") int ttl) throws ResourceNotFoundException; - - /** - * @see RoundRobinPoolApi#deleteRecord(String) - */ - @Named("deleteRecordOfRRPool") - @POST - @Payload("{guid}") - @Fallback(VoidOnNotFoundOr404.class) - ListenableFuture deleteRecord(@PayloadParam("guid") String guid); - - /** - * @see RoundRobinPoolApi#createAAAAPoolForHostname - */ - @Named("addRRLBPool") - @POST - @XMLResponseParser(TextHandler.RRPoolID.class) - @Payload("{zoneName}{hostName}{description}28") - ListenableFuture createAAAAPoolForHostname(@PayloadParam("description") String name, - @PayloadParam("hostName") String hostname) throws ResourceAlreadyExistsException; - - /** - * @see RoundRobinPoolApi#addAAAARecordWithAddressAndTTL - */ - @Named("addRecordToRRPool") - @POST - @XMLResponseParser(TextHandler.Guid.class) - @Payload("") - ListenableFuture addAAAARecordWithAddressAndTTL(@PayloadParam("lbPoolID") String lbPoolID, - @PayloadParam("address") String ipv6Address, @PayloadParam("ttl") int ttl) - throws ResourceAlreadyExistsException; - - /** - * @see RoundRobinPoolApi#delete(String) - */ - @Named("deleteLBPool") - @POST - @Payload("{lbPoolID}Yes") - @Fallback(VoidOnNotFoundOr404.class) - ListenableFuture delete(@PayloadParam("lbPoolID") String id); -} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskApi.java index 5e35e6a03c..a378ba6eea 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskApi.java @@ -18,43 +18,76 @@ */ package org.jclouds.ultradns.ws.features; +import javax.inject.Named; +import javax.ws.rs.POST; + +import org.jclouds.Fallbacks.NullOnNotFoundOr404; +import org.jclouds.Fallbacks.VoidOnNotFoundOr404; 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.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.ultradns.ws.domain.Task; +import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; +import org.jclouds.ultradns.ws.xml.ElementTextHandler; +import org.jclouds.ultradns.ws.xml.TaskHandler; +import org.jclouds.ultradns.ws.xml.TaskListHandler; import com.google.common.collect.FluentIterable; /** - * @see TaskAsyncApi + * @see + * @see * @author Adrian Cole */ +@RequestFilters(SOAPWrapWithPasswordAuth.class) +@VirtualHost public interface TaskApi { /** * Runs a test task * * @return guid of the task created */ - String runTest(String value); + @Named("runTest") + @POST + @XMLResponseParser(ElementTextHandler.Guid.class) + @Payload("{value}") + String runTest(@PayloadParam("value") String value); /** - * Retrieves information about the specified task - * * @param guid * guid of the task to get information about. * @return null if not found */ + @Named("getStatusForTask") + @POST + @XMLResponseParser(TaskHandler.class) + @Payload("{guid}") + @Fallback(NullOnNotFoundOr404.class) @Nullable - Task get(String guid); + Task get(@PayloadParam("guid") String name); /** * Lists all tasks. */ + @Named("getAllTasks") + @POST + @XMLResponseParser(TaskListHandler.class) + @Payload("") FluentIterable list(); - + /** * clears a background task in either a COMPLETE or ERROR state. * * @param guid * guid of the task to clear. */ - void clear(String guid); + @Named("clearTask") + @POST + @Payload("{guid}") + @Fallback(VoidOnNotFoundOr404.class) + void clear(@PayloadParam("guid") String name); } diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskAsyncApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskAsyncApi.java deleted file mode 100644 index 919c37e472..0000000000 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TaskAsyncApi.java +++ /dev/null @@ -1,86 +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.ultradns.ws.features; - -import javax.inject.Named; -import javax.ws.rs.POST; - -import org.jclouds.Fallbacks.NullOnNotFoundOr404; -import org.jclouds.Fallbacks.VoidOnNotFoundOr404; -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.VirtualHost; -import org.jclouds.rest.annotations.XMLResponseParser; -import org.jclouds.ultradns.ws.domain.Task; -import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; -import org.jclouds.ultradns.ws.xml.TextHandler; -import org.jclouds.ultradns.ws.xml.TaskHandler; -import org.jclouds.ultradns.ws.xml.TaskListHandler; - -import com.google.common.collect.FluentIterable; -import com.google.common.util.concurrent.ListenableFuture; - -/** - * @see TaskApi - * @see - * @see - * @author Adrian Cole - */ -@RequestFilters(SOAPWrapWithPasswordAuth.class) -@VirtualHost -public interface TaskAsyncApi { - /** - * @see TaskApi#runTest(String) - */ - @Named("runTest") - @POST - @XMLResponseParser(TextHandler.Guid.class) - @Payload("{value}") - ListenableFuture runTest(@PayloadParam("value") String value); - - /** - * @see TaskApi#get(String) - */ - @Named("getStatusForTask") - @POST - @XMLResponseParser(TaskHandler.class) - @Payload("{guid}") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture get(@PayloadParam("guid") String name); - - /** - * @see TaskApi#list() - */ - @Named("getAllTasks") - @POST - @XMLResponseParser(TaskListHandler.class) - @Payload("") - ListenableFuture> list(); - - /** - * @see TaskApi#clear(String) - */ - @Named("clearTask") - @POST - @Payload("{guid}") - @Fallback(VoidOnNotFoundOr404.class) - ListenableFuture clear(@PayloadParam("guid") String name); -} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java index 4ad9b5eb08..79759943eb 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApi.java @@ -18,30 +18,44 @@ */ package org.jclouds.ultradns.ws.features; +import javax.inject.Named; +import javax.ws.rs.POST; + +import org.jclouds.Fallbacks.NullOnNotFoundOr404; +import org.jclouds.Fallbacks.VoidOnNotFoundOr404; import org.jclouds.javax.annotation.Nullable; import org.jclouds.rest.ResourceNotFoundException; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.Payload; +import org.jclouds.rest.annotations.PayloadParam; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; +import org.jclouds.ultradns.ws.binders.UpdatePoolRecordToXML; import org.jclouds.ultradns.ws.domain.PoolRecordSpec; import org.jclouds.ultradns.ws.domain.TrafficControllerPool; import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord; import org.jclouds.ultradns.ws.domain.UpdatePoolRecord; +import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; +import org.jclouds.ultradns.ws.xml.AttributeHandler; +import org.jclouds.ultradns.ws.xml.ElementTextHandler; +import org.jclouds.ultradns.ws.xml.PoolRecordSpecHandler; +import org.jclouds.ultradns.ws.xml.TrafficControllerPoolListHandler; +import org.jclouds.ultradns.ws.xml.TrafficControllerPoolRecordListHandler; import com.google.common.collect.FluentIterable; /** - * @see TrafficControllerPoolAsyncApi + * @see + * @see * @author Adrian Cole */ +@RequestFilters(SOAPWrapWithPasswordAuth.class) +@VirtualHost public interface TrafficControllerPoolApi { - /** - * Returns all traffic controller pools in the zone. - * - * @throws ResourceNotFoundException - * if the zone doesn't exist - */ - FluentIterable list() throws ResourceNotFoundException; - /** * creates a traffic controller pool. * @@ -54,7 +68,37 @@ public interface TrafficControllerPoolApi { * @throws ResourceAlreadyExistsException * if a pool already exists with the same attrs */ - String createPoolForHostname(String name, String hostname) throws ResourceAlreadyExistsException; + @Named("addTCLBPool") + @POST + @XMLResponseParser(ElementTextHandler.TCPoolID.class) + @Payload("{zoneName}{hostName}{description}1EnabledEnabled0") + String createPoolForHostname(@PayloadParam("description") String name, @PayloadParam("hostName") String hostname) + throws ResourceAlreadyExistsException; + + /** + * Returns all traffic controller pools in the zone. + * + * @throws ResourceNotFoundException + * if the zone doesn't exist + */ + @Named("getLoadBalancingPoolsByZone") + @POST + @XMLResponseParser(TrafficControllerPoolListHandler.class) + @Payload("{zoneName}TC") + FluentIterable list() throws ResourceNotFoundException; + + /** + * Returns all records in the traffic controller pool. + * + * @throws ResourceNotFoundException + * if the pool doesn't exist + */ + @Named("getPoolRecords") + @POST + @XMLResponseParser(TrafficControllerPoolRecordListHandler.class) + @Payload("{poolId}") + FluentIterable listRecords(@PayloadParam("poolId") String poolId) + throws ResourceNotFoundException; /** * Retrieves the name of the specified pool by dname. @@ -64,7 +108,12 @@ public interface TrafficControllerPoolApi { * @return null if not found */ @Nullable - String getNameByDName(String dname); + @Named("getPoolForPoolHostName>") + @POST + @Payload("{hostName}") + @XMLResponseParser(AttributeHandler.PoolName.class) + @Fallback(NullOnNotFoundOr404.class) + String getNameByDName(@PayloadParam("hostName") String dname); /** * removes a pool and all its records and probes @@ -72,15 +121,11 @@ public interface TrafficControllerPoolApi { * @param id * the {@link TrafficControllerPool#getId() id} */ - void delete(String id); - - /** - * Returns all records in the traffic controller pool. - * - * @throws ResourceNotFoundException - * if the pool doesn't exist - */ - FluentIterable listRecords(String poolId) throws ResourceNotFoundException; + @Named("deleteLBPool") + @POST + @Payload("{lbPoolID}Yes") + @Fallback(VoidOnNotFoundOr404.class) + void delete(@PayloadParam("lbPoolID") String id); /** * adds a new record to the pool with default weight. @@ -96,7 +141,12 @@ public interface TrafficControllerPoolApi { * @throws ResourceAlreadyExistsException * if a record already exists with the same attrs */ - String addRecordToPoolWithTTL(String pointsTo, String lbPoolID, int ttl) throws ResourceAlreadyExistsException; + @Named("addPoolRecord") + @POST + @XMLResponseParser(ElementTextHandler.PoolRecordID.class) + @Payload("{poolID}{pointsTo}{ttl}") + String addRecordToPoolWithTTL(@PayloadParam("pointsTo") String pointsTo, @PayloadParam("poolID") String lbPoolID, + @PayloadParam("ttl") int ttl) throws ResourceAlreadyExistsException; /** * adds a new record to the pool with a specified weight. @@ -114,18 +164,26 @@ public interface TrafficControllerPoolApi { * @throws ResourceAlreadyExistsException * if a record already exists with the same attrs */ - String addRecordToPoolWithTTLAndWeight(String pointsTo, String lbPoolID, int ttl, int weight) + @Named("addPoolRecord") + @POST + @XMLResponseParser(ElementTextHandler.PoolRecordID.class) + @Payload("{poolID}{pointsTo}{ttl}{weight}") + String addRecordToPoolWithTTLAndWeight(@PayloadParam("pointsTo") String pointsTo, + @PayloadParam("poolID") String lbPoolID, @PayloadParam("ttl") int ttl, @PayloadParam("weight") int weight) throws ResourceAlreadyExistsException; /** - * Retrieves information about the specified pool record - * * @param poolRecordID * {@link TrafficControllerPoolRecord#getId()} * @return null if not found */ + @Named("getPoolRecordSpec>") + @POST + @Payload("{poolRecordId}") + @XMLResponseParser(PoolRecordSpecHandler.class) + @Fallback(NullOnNotFoundOr404.class) @Nullable - PoolRecordSpec getRecordSpec(String poolRecordID); + PoolRecordSpec getRecordSpec(@PayloadParam("poolRecordId") String poolRecordID); /** * This request updates an existing pool record. @@ -139,7 +197,11 @@ public interface TrafficControllerPoolApi { * @throws ResourceNotFoundException * if the record doesn't exist */ - void updateRecord(String poolRecordID, UpdatePoolRecord update) throws ResourceNotFoundException; + @Named("updatePoolRecord>") + @POST + @MapBinder(UpdatePoolRecordToXML.class) + void updateRecord(@PayloadParam("poolRecordID") String poolRecordID, @PayloadParam("update") UpdatePoolRecord update) + throws ResourceNotFoundException; /** * deletes a specific pooled resource record @@ -147,6 +209,10 @@ public interface TrafficControllerPoolApi { * @param poolRecordID * {@see TrafficControllerPoolRecord#getId()} */ - void deleteRecord(String poolRecordID); + @Named("deletePoolRecord") + @POST + @Payload("{poolRecordID}") + @Fallback(VoidOnNotFoundOr404.class) + void deleteRecord(@PayloadParam("poolRecordID") String poolRecordID); } diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolAsyncApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolAsyncApi.java deleted file mode 100644 index 75e1f39c6a..0000000000 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolAsyncApi.java +++ /dev/null @@ -1,157 +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.ultradns.ws.features; - -import javax.inject.Named; -import javax.ws.rs.POST; - -import org.jclouds.Fallbacks.NullOnNotFoundOr404; -import org.jclouds.Fallbacks.VoidOnNotFoundOr404; -import org.jclouds.rest.ResourceNotFoundException; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.Payload; -import org.jclouds.rest.annotations.PayloadParam; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.VirtualHost; -import org.jclouds.rest.annotations.XMLResponseParser; -import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; -import org.jclouds.ultradns.ws.binders.UpdatePoolRecordToXML; -import org.jclouds.ultradns.ws.domain.PoolRecordSpec; -import org.jclouds.ultradns.ws.domain.TrafficControllerPool; -import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord; -import org.jclouds.ultradns.ws.domain.UpdatePoolRecord; -import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; -import org.jclouds.ultradns.ws.xml.AttributeHandler; -import org.jclouds.ultradns.ws.xml.PoolRecordSpecHandler; -import org.jclouds.ultradns.ws.xml.TextHandler; -import org.jclouds.ultradns.ws.xml.TrafficControllerPoolListHandler; -import org.jclouds.ultradns.ws.xml.TrafficControllerPoolRecordListHandler; - -import com.google.common.collect.FluentIterable; -import com.google.common.util.concurrent.ListenableFuture; - -/** - * @see TrafficControllerPoolApi - * @see - * @see - * @author Adrian Cole - */ -@RequestFilters(SOAPWrapWithPasswordAuth.class) -@VirtualHost -public interface TrafficControllerPoolAsyncApi { - - /** - * @see RoundRobinPoolApi#createPoolForHostname - */ - @Named("addTCLBPool") - @POST - @XMLResponseParser(TextHandler.TCPoolID.class) - @Payload("{zoneName}{hostName}{description}1EnabledEnabled0") - ListenableFuture createPoolForHostname(@PayloadParam("description") String name, - @PayloadParam("hostName") String hostname) throws ResourceAlreadyExistsException; - - /** - * @see TrafficControllerPoolApi#list() - */ - @Named("getLoadBalancingPoolsByZone") - @POST - @XMLResponseParser(TrafficControllerPoolListHandler.class) - @Payload("{zoneName}TC") - ListenableFuture> list() throws ResourceNotFoundException; - - /** - * @see TrafficControllerPoolApi#listRecords(String) - */ - @Named("getPoolRecords") - @POST - @XMLResponseParser(TrafficControllerPoolRecordListHandler.class) - @Payload("{poolId}") - ListenableFuture> listRecords(@PayloadParam("poolId") String poolId) - throws ResourceNotFoundException; - - /** - * @see TrafficControllerPoolApi#getByDName(String) - */ - @Named("getPoolForPoolHostName>") - @POST - @Payload("{hostName}") - @XMLResponseParser(AttributeHandler.PoolName.class) - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture getNameByDName(@PayloadParam("hostName") String dname); - - /** - * @see TrafficControllerPoolApi#delete(String) - */ - @Named("deleteLBPool") - @POST - @Payload("{lbPoolID}Yes") - @Fallback(VoidOnNotFoundOr404.class) - ListenableFuture delete(@PayloadParam("lbPoolID") String id); - - /** - * @see TrafficControllerPoolApi#addRecordToPoolWithTTL - */ - @Named("addPoolRecord") - @POST - @XMLResponseParser(TextHandler.PoolRecordID.class) - @Payload("{poolID}{pointsTo}{ttl}") - ListenableFuture addRecordToPoolWithTTL(@PayloadParam("pointsTo") String pointsTo, - @PayloadParam("poolID") String lbPoolID, @PayloadParam("ttl") int ttl) throws ResourceAlreadyExistsException; - - /** - * @see TrafficControllerPoolApi#addRecordToPoolWithTTLAndWeight - */ - @Named("addPoolRecord") - @POST - @XMLResponseParser(TextHandler.PoolRecordID.class) - @Payload("{poolID}{pointsTo}{ttl}{weight}") - ListenableFuture addRecordToPoolWithTTLAndWeight(@PayloadParam("pointsTo") String pointsTo, - @PayloadParam("poolID") String lbPoolID, @PayloadParam("ttl") int ttl, @PayloadParam("weight") int weight) - throws ResourceAlreadyExistsException; - - /** - * @see TrafficControllerPoolApi#getRecordSpec(String) - */ - @Named("getPoolRecordSpec>") - @POST - @Payload("{poolRecordId}") - @XMLResponseParser(PoolRecordSpecHandler.class) - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture getRecordSpec(@PayloadParam("poolRecordId") String poolRecordID); - - /** - * @see TrafficControllerPoolApi#getRecordSpec(String) - */ - @Named("updatePoolRecord>") - @POST - @MapBinder(UpdatePoolRecordToXML.class) - ListenableFuture updateRecord(@PayloadParam("poolRecordID") String poolRecordID, - @PayloadParam("update") UpdatePoolRecord update) throws ResourceNotFoundException; - - /** - * @see TrafficControllerPoolApi#deleteRecord(String) - */ - @Named("deletePoolRecord") - @POST - @Payload("{poolRecordID}") - @Fallback(VoidOnNotFoundOr404.class) - ListenableFuture deleteRecord(@PayloadParam("poolRecordID") String poolRecordID); - -} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java index ad631f6cd4..5466e434ee 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneApi.java @@ -18,19 +18,36 @@ */ package org.jclouds.ultradns.ws.features; +import javax.inject.Named; +import javax.ws.rs.POST; + +import org.jclouds.Fallbacks.NullOnNotFoundOr404; +import org.jclouds.Fallbacks.VoidOnNotFoundOr404; import org.jclouds.javax.annotation.Nullable; import org.jclouds.rest.ResourceNotFoundException; +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.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; import org.jclouds.ultradns.ws.domain.Zone; import org.jclouds.ultradns.ws.domain.Zone.Type; import org.jclouds.ultradns.ws.domain.ZoneProperties; +import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; +import org.jclouds.ultradns.ws.xml.ZoneListHandler; +import org.jclouds.ultradns.ws.xml.ZonePropertiesHandler; import com.google.common.collect.FluentIterable; /** - * @see ZoneAsyncApi + * @see + * @see * @author Adrian Cole */ +@RequestFilters(SOAPWrapWithPasswordAuth.class) +@VirtualHost public interface ZoneApi { /** @@ -42,25 +59,36 @@ public interface ZoneApi { * @param accountId * the account to create the zone in */ - void createInAccount(String name, String accountId) throws ResourceAlreadyExistsException; + @Named("createPrimaryZone") + @POST + @Payload("{accountId}{zoneName}false") + void createInAccount(@PayloadParam("zoneName") String name, @PayloadParam("accountId") String accountId) + throws ResourceAlreadyExistsException; /** - * Retrieves information about the specified zone - * * @param name * the fully-qualified name, including the trailing dot, of the * zone to get information about. * @return null if not found */ + @Named("getGeneralPropertiesForZone") + @POST + @XMLResponseParser(ZonePropertiesHandler.class) + @Payload("{zoneName}") + @Fallback(NullOnNotFoundOr404.class) @Nullable - ZoneProperties get(String name); + ZoneProperties get(@PayloadParam("zoneName") String name); /** * Lists all zones in the specified account. * * @returns empty if no zones, or account doesn't exist */ - FluentIterable listByAccount(String accountId); + @Named("getZonesOfAccount") + @POST + @XMLResponseParser(ZoneListHandler.class) + @Payload("{accountId}all") + FluentIterable listByAccount(@PayloadParam("accountId") String accountId); /** * Lists all zones in the specified account of type @@ -68,7 +96,12 @@ public interface ZoneApi { * @throws ResourceNotFoundException * if the account doesn't exist */ - FluentIterable listByAccountAndType(String accountId, Type type) throws ResourceNotFoundException; + @Named("getZonesOfAccount") + @POST + @XMLResponseParser(ZoneListHandler.class) + @Payload("{accountId}{zoneType}") + FluentIterable listByAccountAndType(@PayloadParam("accountId") String accountId, + @PayloadParam("zoneType") Type type) throws ResourceNotFoundException; /** * deletes a zone and all its resource records @@ -78,5 +111,9 @@ public interface ZoneApi { * zone you want to delete. * @return null if not found */ - void delete(String name); + @Named("deleteZone") + @POST + @Payload("{zoneName}") + @Fallback(VoidOnNotFoundOr404.class) + void delete(@PayloadParam("zoneName") String name); } diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneAsyncApi.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneAsyncApi.java deleted file mode 100644 index d8d955bd9c..0000000000 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/features/ZoneAsyncApi.java +++ /dev/null @@ -1,100 +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.ultradns.ws.features; - -import javax.inject.Named; -import javax.ws.rs.POST; - -import org.jclouds.Fallbacks.NullOnNotFoundOr404; -import org.jclouds.Fallbacks.VoidOnNotFoundOr404; -import org.jclouds.rest.ResourceNotFoundException; -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.VirtualHost; -import org.jclouds.rest.annotations.XMLResponseParser; -import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; -import org.jclouds.ultradns.ws.domain.Zone; -import org.jclouds.ultradns.ws.domain.Zone.Type; -import org.jclouds.ultradns.ws.domain.ZoneProperties; -import org.jclouds.ultradns.ws.filters.SOAPWrapWithPasswordAuth; -import org.jclouds.ultradns.ws.xml.ZoneListHandler; -import org.jclouds.ultradns.ws.xml.ZonePropertiesHandler; - -import com.google.common.collect.FluentIterable; -import com.google.common.util.concurrent.ListenableFuture; - -/** - * @see ZoneApi - * @see - * @see - * @author Adrian Cole - */ -@RequestFilters(SOAPWrapWithPasswordAuth.class) -@VirtualHost -public interface ZoneAsyncApi { - - /** - * @see ZoneApi#createInAccount(String, String - */ - @Named("createPrimaryZone") - @POST - @Payload("{accountId}{zoneName}false") - ListenableFuture createInAccount(@PayloadParam("zoneName") String name, - @PayloadParam("accountId") String accountId) throws ResourceAlreadyExistsException; - - /** - * @see ZoneApi#get(String) - */ - @Named("getGeneralPropertiesForZone") - @POST - @XMLResponseParser(ZonePropertiesHandler.class) - @Payload("{zoneName}") - @Fallback(NullOnNotFoundOr404.class) - ListenableFuture get(@PayloadParam("zoneName") String name); - - /** - * @see ZoneApi#listByAccount(String) - */ - @Named("getZonesOfAccount") - @POST - @XMLResponseParser(ZoneListHandler.class) - @Payload("{accountId}all") - ListenableFuture> listByAccount(@PayloadParam("accountId") String accountId); - - /** - * @see ZoneApi#listByAccountAndType(String, Type) - */ - @Named("getZonesOfAccount") - @POST - @XMLResponseParser(ZoneListHandler.class) - @Payload("{accountId}{zoneType}") - ListenableFuture> listByAccountAndType(@PayloadParam("accountId") String accountId, - @PayloadParam("zoneType") Type type) throws ResourceNotFoundException; - - /** - * @see ZoneApi#delete(String) - */ - @Named("deleteZone") - @POST - @Payload("{zoneName}") - @Fallback(VoidOnNotFoundOr404.class) - ListenableFuture delete(@PayloadParam("zoneName") String name); -} diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicates.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicates.java index 89067ab839..3a358beab0 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicates.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicates.java @@ -32,15 +32,6 @@ import com.google.common.base.Predicate; */ public class TrafficControllerPoolPredicates { - /** - * evaluates to true if the input {@link TrafficControllerPool} exists - * with {@link TrafficControllerPool#getId() id} corresponding to the - * {@code id} parameter. - * - * @param id - * the {@link TrafficControllerPool#getId() id} of the - * desired pool record - */ public static Predicate idEqualTo(String id) { return new IdEqualToPredicate(id); } @@ -54,9 +45,7 @@ public class TrafficControllerPoolPredicates { @Override public boolean apply(TrafficControllerPool input) { - if (input == null) - return false; - return id.equals(input.getId()); + return input != null && id.equals(input.getId()); } @Override @@ -65,36 +54,25 @@ public class TrafficControllerPoolPredicates { } } - /** - * evaluates to true if the input {@link TrafficControllerPoolRecord} exists - * with {@link TrafficControllerPoolRecord#getId() id} corresponding to the - * {@code recordId} parameter. - * - * @param recordId - * the {@link TrafficControllerPoolRecord#getId() id} of the - * desired pool record - */ public static Predicate recordIdEqualTo(String recordId) { return new RecordIdEqualToPredicate(recordId); } private static final class RecordIdEqualToPredicate implements Predicate { - private final String id; + private final String recordId; - public RecordIdEqualToPredicate(String id) { - this.id = checkNotNull(id, "recordId"); + public RecordIdEqualToPredicate(String recordId) { + this.recordId = checkNotNull(recordId, "recordId"); } @Override public boolean apply(TrafficControllerPoolRecord input) { - if (input == null) - return false; - return id.equals(input.getId()); + return input != null && recordId.equals(input.getId()); } @Override public String toString() { - return "RecordIdEqualTo(" + id + ")"; + return "RecordIdEqualTo(" + recordId + ")"; } } } diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/predicates/ZonePredicates.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/predicates/ZonePredicates.java index 72e6b84b31..21d8a68433 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/predicates/ZonePredicates.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/predicates/ZonePredicates.java @@ -32,22 +32,25 @@ import com.google.common.base.Predicate; */ public class ZonePredicates { - /** - * matches zones of the given type - */ - public static Predicate typeEquals(final Type type) { - checkNotNull(type, "type must be defined"); + public static Predicate typeEqualTo(Type type) { + return new TypeEqualToPredicate(type); + } - return new Predicate() { - @Override - public boolean apply(Zone zone) { - return type.equals(zone.getType()); - } + private static final class TypeEqualToPredicate implements Predicate { + private final Type type; - @Override - public String toString() { - return "typeEquals(" + type + ")"; - } - }; + public TypeEqualToPredicate(Type type) { + this.type = checkNotNull(type, "type"); + } + + @Override + public boolean apply(Zone input) { + return input != null && type.equals(input.getType()); + } + + @Override + public String toString() { + return "TypeEqualTo(" + type + ")"; + } } } diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/AttributeHandler.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/AttributeHandler.java index 5dc9b32d86..117364562d 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/AttributeHandler.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/AttributeHandler.java @@ -37,7 +37,7 @@ public abstract class AttributeHandler extends ParseSax.HandlerForGeneratedReque } } - private String attributeName; + private final String attributeName; private String attribute = null; private AttributeHandler(String attributeName) { @@ -46,11 +46,7 @@ public abstract class AttributeHandler extends ParseSax.HandlerForGeneratedReque @Override public String getResult() { - try { - return checkNotNull(attribute, "%s not present in the response", attributeName); - } finally { - attribute = null; - } + return checkNotNull(attribute, "%s not present in the response", attributeName); } @Override diff --git a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/TextHandler.java b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ElementTextHandler.java similarity index 78% rename from providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/TextHandler.java rename to providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ElementTextHandler.java index ce59512213..3fa4fa939d 100644 --- a/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/TextHandler.java +++ b/providers/ultradns-ws/src/main/java/org/jclouds/ultradns/ws/xml/ElementTextHandler.java @@ -28,48 +28,44 @@ import org.jclouds.http.functions.ParseSax; * * @author Adrian Cole */ -public abstract class TextHandler extends ParseSax.HandlerForGeneratedRequestWithResult { +public abstract class ElementTextHandler extends ParseSax.HandlerForGeneratedRequestWithResult { - public static class Guid extends TextHandler { + public static class Guid extends ElementTextHandler { public Guid() { super("guid"); } } - public static class RRPoolID extends TextHandler { + public static class RRPoolID extends ElementTextHandler { public RRPoolID() { super("RRPoolID"); } } - public static class TCPoolID extends TextHandler { + public static class TCPoolID extends ElementTextHandler { public TCPoolID() { super("TCPoolID"); } } - public static class PoolRecordID extends TextHandler { + public static class PoolRecordID extends ElementTextHandler { public PoolRecordID() { super("poolRecordID"); } } - private String textElement; + private final String textElement; private StringBuilder currentText = new StringBuilder(); private String text = null; - private TextHandler(String textElement) { + private ElementTextHandler(String textElement) { this.textElement = checkNotNull(textElement, "textElement"); } @Override public String getResult() { - try { - return checkNotNull(text, "%s not present in the response", textElement); - } finally { - text = null; - } + return checkNotNull(text, "%s not present in the response", textElement); } @Override diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/UltraDNSWSApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/UltraDNSWSApiLiveTest.java index 66a3293dd1..bfc2f492a6 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/UltraDNSWSApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/UltraDNSWSApiLiveTest.java @@ -18,7 +18,7 @@ */ package org.jclouds.ultradns.ws; -import static com.google.common.base.Preconditions.checkNotNull; +import static org.testng.Assert.assertNotNull; import org.jclouds.ultradns.ws.domain.Account; import org.jclouds.ultradns.ws.internal.BaseUltraDNSWSApiLiveTest; @@ -37,7 +37,7 @@ public class UltraDNSWSApiLiveTest extends BaseUltraDNSWSApiLiveTest { } private void checkAccount(Account account) { - checkNotNull(account.getId(), "Id cannot be null for an Account."); - checkNotNull(account.getName(), "Name cannot be null for Account %s", account); + assertNotNull(account.getId(), "Id cannot be null for " + account); + assertNotNull(account.getName(), "Name cannot be null for " + account); } } diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiLiveTest.java index d7cfb53b52..ea8f08e309 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ResourceRecordApiLiveTest.java @@ -17,12 +17,12 @@ * under the License. */ package org.jclouds.ultradns.ws.features; - -import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Predicates.equalTo; +import static java.lang.String.format; import static java.util.logging.Logger.getAnonymousLogger; import static org.jclouds.ultradns.ws.domain.ResourceRecord.rrBuilder; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -72,20 +72,20 @@ public class ResourceRecordApiLiveTest extends BaseUltraDNSWSApiLiveTest { } static void checkResourceRecord(ResourceRecord rr) { - checkNotNull(rr.getName(), "DName cannot be null for a ResourceRecord %s", rr); - checkNotNull(rr.getType(), "Type cannot be null for a ResourceRecord %s", rr); - assertTrue(rr.getType() > 0, "Type must be unsigned for a ResourceRecord " + rr); - checkNotNull(rr.getType(), "Type cannot be null for a ResourceRecord %s", rr); - checkNotNull(rr.getTTL(), "TTL cannot be null for a ResourceRecord %s", rr); - checkNotNull(rr.getRData(), "InfoValues cannot be null for a ResourceRecord %s", rr); + assertNotNull(rr.getName(), "DName cannot be null for " + rr); + assertNotNull(rr.getType(), "Type cannot be null for " + rr); + assertTrue(rr.getType() > 0, "Type must be unsigned for " + rr); + assertNotNull(rr.getType(), "Type cannot be null for " + rr); + assertNotNull(rr.getTTL(), "TTL cannot be null for " + rr); + assertNotNull(rr.getRData(), "InfoValues cannot be null for " + rr); } static void checkResourceRecordMetadata(ResourceRecordMetadata rr) { - checkNotNull(rr.getZoneId(), "ZoneId cannot be null for a ResourceRecordMetadata %s", rr); - checkNotNull(rr.getGuid(), "Guid cannot be null for a ResourceRecordMetadata %s", rr); - checkNotNull(rr.getZoneName(), "ZoneName cannot be null for a ResourceRecordMetadata %s", rr); - checkNotNull(rr.getCreated(), "Created cannot be null for a ResourceRecordMetadata %s", rr); - checkNotNull(rr.getModified(), "Modified cannot be null for a ResourceRecordMetadata %s", rr); + assertNotNull(rr.getZoneId(), "ZoneId cannot be null for " + rr); + assertNotNull(rr.getGuid(), "Guid cannot be null for " + rr); + assertNotNull(rr.getZoneName(), "ZoneName cannot be null for " + rr); + assertNotNull(rr.getCreated(), "Created cannot be null for " + rr); + assertNotNull(rr.getModified(), "Modified cannot be null for " + rr); checkResourceRecord(rr.getRecord()); } @@ -113,8 +113,7 @@ public class ResourceRecordApiLiveTest extends BaseUltraDNSWSApiLiveTest { void logSummary() { getAnonymousLogger().info("zoneCount: " + zones); for (Entry entry : recordTypeCounts.asMap().entrySet()) - getAnonymousLogger().info( - String.format("type: %s, count: %s", entry.getKey(), entry.getValue())); + getAnonymousLogger().info(format("type: %s, count: %s", entry.getKey(), entry.getValue())); } @Test(expectedExceptions = ResourceNotFoundException.class, expectedExceptionsMessageRegExp = "Zone does not exist in the system.") diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApiLiveTest.java index 830b79d583..29ee70a8a3 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/RoundRobinPoolApiLiveTest.java @@ -18,12 +18,12 @@ */ package org.jclouds.ultradns.ws.features; -import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Predicates.equalTo; import static java.util.logging.Logger.getAnonymousLogger; import static org.jclouds.ultradns.ws.domain.ResourceRecord.rrBuilder; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -62,10 +62,10 @@ public class RoundRobinPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest { } private void checkRRPool(RoundRobinPool pool) { - checkNotNull(pool.getZoneId(), "ZoneId cannot be null for a RoundRobinPool %s", pool); - checkNotNull(pool.getId(), "Id cannot be null for a RoundRobinPool %s", pool); - checkNotNull(pool.getName(), "Name cannot be null for a RoundRobinPool %s", pool); - checkNotNull(pool.getDName(), "DName cannot be null for a RoundRobinPool %s", pool); + assertNotNull(pool.getZoneId(), "ZoneId cannot be null for " + pool); + assertNotNull(pool.getId(), "Id cannot be null for " + pool); + assertNotNull(pool.getName(), "Name cannot be null for " + pool); + assertNotNull(pool.getDName(), "DName cannot be null for " + pool); } @Test diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TaskApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TaskApiLiveTest.java index 29dc6bb145..e20afc930b 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TaskApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TaskApiLiveTest.java @@ -18,8 +18,8 @@ */ package org.jclouds.ultradns.ws.features; -import static com.google.common.base.Preconditions.checkNotNull; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import org.jclouds.ultradns.ws.domain.Task; @@ -33,10 +33,10 @@ import org.testng.annotations.Test; public class TaskApiLiveTest extends BaseUltraDNSWSApiLiveTest { private void checkTask(Task task) { - checkNotNull(task.getGuid(), "Guid cannot be null for a Task %s", task); - checkNotNull(task.getStatusCode(), "StatusCode cannot be null for a Task %s", task); - checkNotNull(task.getMessage(), "While Message can be null for a Task, its Optional wrapper cannot %s", task); - checkNotNull(task.getResultUrl(), "While ResultUrl can be null for a Task, its Optional wrapper cannot %s", task); + assertNotNull(task.getGuid(), "Guid cannot be null for " + task); + assertNotNull(task.getStatusCode(), "StatusCode cannot be null for " + task); + assertNotNull(task.getMessage(), "While Message can be null, its Optional wrapper cannot " + task); + assertNotNull(task.getResultUrl(), "While ResultUrl can be null, its Optional wrapper cannot " + task); } @Test diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApiLiveTest.java index cacdb6ca7d..f0480698c9 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/TrafficControllerPoolApiLiveTest.java @@ -18,12 +18,12 @@ */ package org.jclouds.ultradns.ws.features; -import static com.google.common.base.Preconditions.checkNotNull; import static java.util.logging.Logger.getAnonymousLogger; import static org.jclouds.ultradns.ws.predicates.TrafficControllerPoolPredicates.idEqualTo; import static org.jclouds.ultradns.ws.predicates.TrafficControllerPoolPredicates.recordIdEqualTo; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -65,10 +65,10 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest } private void checkTCPool(TrafficControllerPool pool) { - checkNotNull(pool.getZoneId(), "ZoneId cannot be null for %s", pool); - checkNotNull(pool.getId(), "Id cannot be null for %s", pool); - checkNotNull(pool.getName(), "Name cannot be null for %s", pool); - checkNotNull(pool.getDName(), "DName cannot be null for %s", pool); + assertNotNull(pool.getZoneId(), "ZoneId cannot be null " + pool); + assertNotNull(pool.getId(), "Id cannot be null " + pool); + assertNotNull(pool.getName(), "Name cannot be null " + pool); + assertNotNull(pool.getDName(), "DName cannot be null " + pool); assertEquals(api(zoneName).getNameByDName(pool.getDName()), pool.getName()); } @@ -104,21 +104,21 @@ public class TrafficControllerPoolApiLiveTest extends BaseUltraDNSWSApiLiveTest } static TrafficControllerPoolRecord checkTrafficControllerPoolRecord(TrafficControllerPoolRecord record) { - checkNotNull(record.getId(), "Id cannot be null for %s", record); - checkNotNull(record.getPoolId(), "PoolId cannot be null for %s", record); - checkNotNull(record.getPointsTo(), "PointsTo cannot be null for %s", record); + assertNotNull(record.getId(), "Id cannot be null for " + record); + assertNotNull(record.getPoolId(), "PoolId cannot be null for " + record); + assertNotNull(record.getPointsTo(), "PointsTo cannot be null for " + record); assertTrue(record.getWeight() >= 0, "Weight must be unsigned for " + record); assertTrue(record.getPriority() >= 0, "Priority must be unsigned for " + record); - checkNotNull(record.getType(), "Type cannot be null for %s", record); - checkNotNull(record.getStatus(), "Status cannot be null for %s", record); + assertNotNull(record.getType(), "Type cannot be null for " + record); + assertNotNull(record.getStatus(), "Status cannot be null for " + record); assertTrue(record.getStatus() != Status.UNRECOGNIZED, "unrecognized status for " + record); - checkNotNull(record.getDescription(), "Description cannot be null for %s", record); + assertNotNull(record.getDescription(), "Description cannot be null for " + record); return record; } static PoolRecordSpec checkPoolRecordSpec(PoolRecordSpec record) { - checkNotNull(record.getDescription(), "Description cannot be null for %s", record); - checkNotNull(record.getState(), "State cannot be null for %s", record); + assertNotNull(record.getDescription(), "Description cannot be null for " + record); + assertNotNull(record.getState(), "State cannot be null for " + record); // TODO: collect all possible states then consider enum assertTrue(ImmutableSet.of("Normal", "Normal-NoTest").contains(record.getState()), "Unknown State for " + record); assertTrue(record.getWeight() >= 0, "Weight must be unsigned for " + record); diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ZoneApiLiveTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ZoneApiLiveTest.java index 430259a17a..3c4df6aa61 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ZoneApiLiveTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/features/ZoneApiLiveTest.java @@ -18,11 +18,11 @@ */ package org.jclouds.ultradns.ws.features; -import static com.google.common.base.Preconditions.checkNotNull; import static java.util.logging.Logger.getAnonymousLogger; import static org.jclouds.ultradns.ws.domain.Zone.Type.PRIMARY; -import static org.jclouds.ultradns.ws.predicates.ZonePredicates.typeEquals; +import static org.jclouds.ultradns.ws.predicates.ZonePredicates.typeEqualTo; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -55,17 +55,16 @@ public class ZoneApiLiveTest extends BaseUltraDNSWSApiLiveTest { } private void checkZone(Zone zone) { - checkNotNull(zone.getId(), "Id cannot be null for a Zone %s", zone); - checkNotNull(zone.getName(), "Name cannot be null for a Zone %s", zone); - checkNotNull(zone.getType(), "Type cannot be null for a Zone %s", zone); - checkNotNull(zone.getTypeCode(), "TypeCode cannot be null for a Zone %s", zone); + assertNotNull(zone.getId(), "Id cannot be null for " + zone); + assertNotNull(zone.getName(), "Name cannot be null for " + zone); + assertNotNull(zone.getType(), "Type cannot be null for " + zone); + assertNotNull(zone.getTypeCode(), "TypeCode cannot be null for " + zone); assertEquals(zone.getTypeCode(), zone.getType().getCode()); - checkNotNull(zone.getAccountId(), "AccountId cannot be null for a Zone %s", zone); + assertNotNull(zone.getAccountId(), "AccountId cannot be null for " + zone); assertEquals(zone.getAccountId(), account.getId()); - checkNotNull(zone.getOwnerId(), "OwnerId cannot be null for a Zone %s", zone); - checkNotNull(zone.getDNSSECStatus(), "DNSSECStatus cannot be null for a Zone %s", zone); - checkNotNull(zone.getPrimarySrc(), "While PrimarySrc can be null for a Zone, its Optional wrapper cannot %s", - zone); + assertNotNull(zone.getOwnerId(), "OwnerId cannot be null for " + zone); + assertNotNull(zone.getDNSSECStatus(), "DNSSECStatus cannot be null for " + zone); + assertNotNull(zone.getPrimarySrc(), "While PrimarySrc can be null, its Optional wrapper cannot " + zone); } @Test @@ -76,9 +75,9 @@ public class ZoneApiLiveTest extends BaseUltraDNSWSApiLiveTest { checkZone(zone); } - if (response.anyMatch(typeEquals(PRIMARY))) { + if (response.anyMatch(typeEqualTo(PRIMARY))) { assertEquals(api().listByAccountAndType(account.getId(), PRIMARY).toSet(), response - .filter(typeEquals(PRIMARY)).toSet()); + .filter(typeEqualTo(PRIMARY)).toSet()); } } @@ -94,7 +93,7 @@ public class ZoneApiLiveTest extends BaseUltraDNSWSApiLiveTest { assertEquals(zoneProperties.getName(), zone.getName()); assertEquals(zoneProperties.getType(), zone.getType()); assertEquals(zoneProperties.getTypeCode(), zone.getTypeCode()); - checkNotNull(zoneProperties.getModified(), "Modified cannot be null for a Zone %s", zone); + assertNotNull(zoneProperties.getModified(), "Modified cannot be null for " + zone); assertTrue(zoneProperties.getResourceRecordCount() >= 0, "ResourceRecordCount must be positive or zero for a Zone " + zone); } @@ -134,7 +133,7 @@ public class ZoneApiLiveTest extends BaseUltraDNSWSApiLiveTest { assertEquals(newZone.getName(), name); assertEquals(newZone.getType(), Type.PRIMARY); assertEquals(newZone.getTypeCode(), Type.PRIMARY.getCode()); - checkNotNull(newZone.getModified(), "Modified cannot be null for a Zone %s", newZone); + assertNotNull(newZone.getModified(), "Modified cannot be null for " + newZone); assertEquals(newZone.getResourceRecordCount(), 5); } finally { api().delete(name); diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/RunTestResponseTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/RunTestResponseTest.java index 70b6edbee0..28452378f3 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/RunTestResponseTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/parse/RunTestResponseTest.java @@ -23,7 +23,7 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; import org.jclouds.http.functions.BaseHandlerTest; -import org.jclouds.ultradns.ws.xml.TextHandler; +import org.jclouds.ultradns.ws.xml.ElementTextHandler; import org.testng.annotations.Test; /** @@ -35,7 +35,7 @@ public class RunTestResponseTest extends BaseHandlerTest { public void test() { InputStream is = getClass().getResourceAsStream("/taskid.xml"); - TextHandler.Guid handler = injector.getInstance(TextHandler.Guid.class); + ElementTextHandler.Guid handler = injector.getInstance(ElementTextHandler.Guid.class); assertEquals(factory.create(handler).parse(is), "8d7a1725-4f4a-4b70-affa-f01dcce1526e"); } } diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicatesTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicatesTest.java index 0ffadd663a..528ae26998 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicatesTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/predicates/TrafficControllerPoolPredicatesTest.java @@ -20,6 +20,8 @@ package org.jclouds.ultradns.ws.predicates; import static org.jclouds.ultradns.ws.predicates.TrafficControllerPoolPredicates.idEqualTo; import static org.jclouds.ultradns.ws.predicates.TrafficControllerPoolPredicates.recordIdEqualTo; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; import org.jclouds.ultradns.ws.domain.TrafficControllerPool; import org.jclouds.ultradns.ws.domain.TrafficControllerPoolRecord; @@ -43,12 +45,12 @@ public class TrafficControllerPoolPredicatesTest { @Test public void testIdEqualToWhenEqual() { - assert idEqualTo("000000000000002").apply(pool); + assertTrue(idEqualTo("000000000000002").apply(pool)); } @Test public void testIdEqualToWhenNotEqual() { - assert !idEqualTo("000000000000003").apply(pool); + assertFalse(idEqualTo("000000000000003").apply(pool)); } TrafficControllerPoolRecord record = TrafficControllerPoolRecord.builder() @@ -66,11 +68,11 @@ public class TrafficControllerPoolPredicatesTest { @Test public void testRecordIdEqualToWhenEqual() { - assert recordIdEqualTo("0000000000000001").apply(record); + assertTrue(recordIdEqualTo("0000000000000001").apply(record)); } @Test public void testRecordIdEqualToWhenNotEqual() { - assert !recordIdEqualTo("0000000000000002").apply(record); + assertFalse(recordIdEqualTo("0000000000000002").apply(record)); } } diff --git a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/predicates/ZonePredicatesTest.java b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/predicates/ZonePredicatesTest.java index 88d3883cba..1466044799 100644 --- a/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/predicates/ZonePredicatesTest.java +++ b/providers/ultradns-ws/src/test/java/org/jclouds/ultradns/ws/predicates/ZonePredicatesTest.java @@ -18,7 +18,9 @@ */ package org.jclouds.ultradns.ws.predicates; -import static org.jclouds.ultradns.ws.predicates.ZonePredicates.typeEquals; +import static org.jclouds.ultradns.ws.predicates.ZonePredicates.typeEqualTo; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; import org.jclouds.ultradns.ws.domain.Zone; import org.jclouds.ultradns.ws.domain.Zone.DNSSECStatus; @@ -41,11 +43,11 @@ public class ZonePredicatesTest { @Test public void testTypeEqualsWhenEqual() { - assert typeEquals(Type.PRIMARY).apply(zone); + assertTrue(typeEqualTo(Type.PRIMARY).apply(zone)); } @Test public void testTypeEqualsWhenNotEqual() { - assert !typeEquals(Type.SECONDARY).apply(zone); + assertFalse(typeEqualTo(Type.SECONDARY).apply(zone)); } }