Issue 825:add means to use login as opposed to signature authentication in cloudstack

This commit is contained in:
Adrian Cole 2012-01-31 19:53:04 -08:00
parent 5e23d34f91
commit ec104454b1
50 changed files with 712 additions and 134 deletions

View File

@ -0,0 +1,48 @@
/**
* 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.cloudstack.config;
import org.jclouds.compute.ComputeServiceContextFactory;
/**
* Configuration properties and constants used in CloudStack connections.
*
* @author Adrian Cole
*/
public interface CloudStackProperties {
/**
* Type of credentials specified during {@link ComputeServiceContextFactory#createContext}. If
* {@link CredentialType#API_ACCESS_KEY_CREDENTIALS}, the request signing is used. If
* {@link CredentialType#PASSWORD_CREDENTIALS}, login will happen and a session will be
* persisted.
*
* <h3>valid values</h3>
* <ul>
* <li>apiAccessKeyCredentials</li>
* <li>passwordCredentials</li>
* </ul>
*
* @see CredentialType
* @see <a href="http://docs.cloud.com/CloudStack_Documentation/Customizing_the_CloudStack_UI#Cross_Site_Request_Forgery_%28CSRF%29"
* />
*/
public static final String CREDENTIAL_TYPE = "jclouds.cloudstack.credential-type";
}

View File

@ -18,11 +18,16 @@
*/
package org.jclouds.cloudstack.config;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Named;
import static com.google.common.base.Throwables.propagate;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.core.UriBuilder;
import org.jclouds.Constants;
import org.jclouds.cloudstack.CloudStackAsyncClient;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.CloudStackDomainAsyncClient;
@ -30,6 +35,7 @@ import org.jclouds.cloudstack.CloudStackDomainClient;
import org.jclouds.cloudstack.CloudStackGlobalAsyncClient;
import org.jclouds.cloudstack.CloudStackGlobalClient;
import org.jclouds.cloudstack.collections.Integration;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.cloudstack.features.AccountAsyncClient;
import org.jclouds.cloudstack.features.AccountClient;
import org.jclouds.cloudstack.features.AddressAsyncClient;
@ -110,8 +116,16 @@ import org.jclouds.cloudstack.features.VolumeAsyncClient;
import org.jclouds.cloudstack.features.VolumeClient;
import org.jclouds.cloudstack.features.ZoneAsyncClient;
import org.jclouds.cloudstack.features.ZoneClient;
import org.jclouds.cloudstack.filters.AddSessionKeyAndJSessionIdToRequest;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.functions.LoginWithPasswordCredentials;
import org.jclouds.cloudstack.handlers.CloudStackErrorHandler;
import org.jclouds.cloudstack.handlers.RetryOnRenewAndLogoutOnClose;
import org.jclouds.concurrent.RetryOnTimeOutExceptionFunction;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
@ -124,9 +138,17 @@ import org.jclouds.rest.config.BinderUtils;
import org.jclouds.rest.config.RestClientModule;
import org.jclouds.rest.internal.RestContextImpl;
import javax.ws.rs.core.UriBuilder;
import java.net.URI;
import java.util.Map;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Named;
/**
* Configures the cloudstack connection.
@ -138,47 +160,47 @@ import java.util.Map;
public class CloudStackRestClientModule extends RestClientModule<CloudStackClient, CloudStackAsyncClient> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(ZoneClient.class, ZoneAsyncClient.class)//
.put(GlobalZoneClient.class, GlobalZoneAsyncClient.class)//
.put(TemplateClient.class, TemplateAsyncClient.class)//
.put(OfferingClient.class, OfferingAsyncClient.class)//
.put(NetworkClient.class, NetworkAsyncClient.class)//
.put(VirtualMachineClient.class, VirtualMachineAsyncClient.class)//
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)//
.put(AsyncJobClient.class, AsyncJobAsyncClient.class)//
.put(AddressClient.class, AddressAsyncClient.class)//
.put(NATClient.class, NATAsyncClient.class)//
.put(FirewallClient.class, FirewallAsyncClient.class)//
.put(LoadBalancerClient.class, LoadBalancerAsyncClient.class)//
.put(GuestOSClient.class, GuestOSAsyncClient.class)//
.put(HypervisorClient.class, HypervisorAsyncClient.class)//
.put(ConfigurationClient.class, ConfigurationAsyncClient.class)//
.put(GlobalConfigurationClient.class, GlobalConfigurationAsyncClient.class)//
.put(AccountClient.class, AccountAsyncClient.class)//
.put(DomainAccountClient.class, DomainAccountAsyncClient.class)//
.put(DomainUserClient.class, DomainUserAsyncClient.class)//
.put(DomainDomainClient.class, DomainDomainAsyncClient.class)//
.put(GlobalDomainClient.class, GlobalDomainAsyncClient.class)//
.put(GlobalAccountClient.class, GlobalAccountAsyncClient.class)//
.put(GlobalUserClient.class, GlobalUserAsyncClient.class)//
.put(EventClient.class, EventAsyncClient.class)//
.put(LimitClient.class, LimitAsyncClient.class)//
.put(DomainLimitClient.class, DomainLimitAsyncClient.class)//
.put(SSHKeyPairClient.class, SSHKeyPairAsyncClient.class)//
.put(VMGroupClient.class, VMGroupAsyncClient.class)//
.put(ISOClient.class, ISOAsyncClient.class)//
.put(VolumeClient.class, VolumeAsyncClient.class)//
.put(SnapshotClient.class, SnapshotAsyncClient.class)//
.put(GlobalAlertClient.class, GlobalAlertAsyncClient.class)//
.put(GlobalCapacityClient.class, GlobalCapacityAsyncClient.class)//
.put(GlobalOfferingClient.class, GlobalOfferingAsyncClient.class)//
.put(GlobalHostClient.class, GlobalHostAsyncClient.class)//
.put(GlobalStoragePoolClient.class, GlobalStoragePoolAsyncClient.class)//
.put(GlobalUsageClient.class, GlobalUsageAsyncClient.class)//
.put(GlobalPodClient.class, GlobalPodAsyncClient.class)//
.put(GlobalVlanClient.class, GlobalVlanAsyncClient.class)//
.put(SessionClient.class, SessionAsyncClient.class)//
.build();
.put(ZoneClient.class, ZoneAsyncClient.class)//
.put(GlobalZoneClient.class, GlobalZoneAsyncClient.class)//
.put(TemplateClient.class, TemplateAsyncClient.class)//
.put(OfferingClient.class, OfferingAsyncClient.class)//
.put(NetworkClient.class, NetworkAsyncClient.class)//
.put(VirtualMachineClient.class, VirtualMachineAsyncClient.class)//
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)//
.put(AsyncJobClient.class, AsyncJobAsyncClient.class)//
.put(AddressClient.class, AddressAsyncClient.class)//
.put(NATClient.class, NATAsyncClient.class)//
.put(FirewallClient.class, FirewallAsyncClient.class)//
.put(LoadBalancerClient.class, LoadBalancerAsyncClient.class)//
.put(GuestOSClient.class, GuestOSAsyncClient.class)//
.put(HypervisorClient.class, HypervisorAsyncClient.class)//
.put(ConfigurationClient.class, ConfigurationAsyncClient.class)//
.put(GlobalConfigurationClient.class, GlobalConfigurationAsyncClient.class)//
.put(AccountClient.class, AccountAsyncClient.class)//
.put(DomainAccountClient.class, DomainAccountAsyncClient.class)//
.put(DomainUserClient.class, DomainUserAsyncClient.class)//
.put(DomainDomainClient.class, DomainDomainAsyncClient.class)//
.put(GlobalDomainClient.class, GlobalDomainAsyncClient.class)//
.put(GlobalAccountClient.class, GlobalAccountAsyncClient.class)//
.put(GlobalUserClient.class, GlobalUserAsyncClient.class)//
.put(EventClient.class, EventAsyncClient.class)//
.put(LimitClient.class, LimitAsyncClient.class)//
.put(DomainLimitClient.class, DomainLimitAsyncClient.class)//
.put(SSHKeyPairClient.class, SSHKeyPairAsyncClient.class)//
.put(VMGroupClient.class, VMGroupAsyncClient.class)//
.put(ISOClient.class, ISOAsyncClient.class)//
.put(VolumeClient.class, VolumeAsyncClient.class)//
.put(SnapshotClient.class, SnapshotAsyncClient.class)//
.put(GlobalAlertClient.class, GlobalAlertAsyncClient.class)//
.put(GlobalCapacityClient.class, GlobalCapacityAsyncClient.class)//
.put(GlobalOfferingClient.class, GlobalOfferingAsyncClient.class)//
.put(GlobalHostClient.class, GlobalHostAsyncClient.class)//
.put(GlobalStoragePoolClient.class, GlobalStoragePoolAsyncClient.class)//
.put(GlobalUsageClient.class, GlobalUsageAsyncClient.class)//
.put(GlobalPodClient.class, GlobalPodAsyncClient.class)//
.put(GlobalVlanClient.class, GlobalVlanAsyncClient.class)//
.put(SessionClient.class, SessionAsyncClient.class)//
.build();
@Override
protected void bindAsyncClient() {
@ -214,6 +236,8 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
}).to(new TypeLiteral<RestContextImpl<CloudStackGlobalClient, CloudStackGlobalAsyncClient>>() {
});
install(new CloudStackParserModule());
bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class);
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenewAndLogoutOnClose.class);
super.configure();
}
@ -228,9 +252,91 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
@Provides
@Integration
protected URI providesIntegrationEndpoint(@Provider URI normal,
@Named("jclouds.cloudstack.integration-api-port") int port,
com.google.inject.Provider<UriBuilder> uriBuilder) {
return uriBuilder.get().scheme(normal.getScheme())
.host(normal.getHost()).path("/").port(port).build();
@Named("jclouds.cloudstack.integration-api-port") int port,
com.google.inject.Provider<UriBuilder> uriBuilder) {
return uriBuilder.get().scheme(normal.getScheme()).host(normal.getHost()).path("/").port(port).build();
}
/**
* Session client is used in login-related functionality
*/
@Provides
@Singleton
protected SessionClient bindSessionClient(CloudStackClient client) {
return client.getSessionClient();
}
@Singleton
static class CredentialTypeFromPropertyOrDefault implements javax.inject.Provider<CredentialType> {
/**
* use optional injection to supply a default value for credential type. so that we don't have
* to set a default property.
*/
@Inject(optional = true)
@Named(CloudStackProperties.CREDENTIAL_TYPE)
String credentialType = CredentialType.API_ACCESS_KEY_CREDENTIALS.toString();
@Override
public CredentialType get() {
return CredentialType.fromValue(credentialType);
}
}
/**
* we use the type of credentials specified at login to determine which way we want to filter the
* request. <br/>
* for ex, if we are getting passwords, we know we will need to login/logout. Otherwise we are
* signing requests.
*/
@Provides
@Singleton
protected AuthenticationFilter authenticationFilterForCredentialType(CredentialType credentialType,
AddSessionKeyAndJSessionIdToRequest addSessionKeyAndJSessionIdToRequest, QuerySigner querySigner) {
switch (credentialType) {
case PASSWORD_CREDENTIALS:
return addSessionKeyAndJSessionIdToRequest;
case API_ACCESS_KEY_CREDENTIALS:
return querySigner;
default:
throw new IllegalArgumentException("credential type not supported: " + credentialType);
}
}
@Provides
@Singleton
protected Function<Credentials, LoginResponse> makeSureFilterRetriesOnTimeout(
LoginWithPasswordCredentials loginWithPasswordCredentials) {
// we should retry on timeout exception logging in.
return new RetryOnTimeOutExceptionFunction<Credentials, LoginResponse>(loginWithPasswordCredentials);
}
// TODO: not sure we can action the timeout from loginresponse without extra code? modify default
// accordingly
// PROPERTY_SESSION_INTERVAL is default to 60 seconds
@Provides
@Singleton
public LoadingCache<Credentials, LoginResponse> provideLoginResponseCache(
Function<Credentials, LoginResponse> getLoginResponse,
@Named(Constants.PROPERTY_SESSION_INTERVAL) int seconds) {
return CacheBuilder.newBuilder().expireAfterWrite(seconds, TimeUnit.SECONDS).build(
CacheLoader.from(getLoginResponse));
}
// Temporary conversion of a cache to a supplier until there is a single-element cache
// http://code.google.com/p/guava-libraries/issues/detail?id=872
@Provides
@Singleton
protected Supplier<LoginResponse> provideLoginResponseSupplier(final LoadingCache<Credentials, LoginResponse> cache,
@Provider final Credentials creds) {
return new Supplier<LoginResponse>() {
@Override
public LoginResponse get() {
try {
return cache.get(creds);
} catch (ExecutionException e) {
throw propagate(e.getCause());
}
}
};
}
}

View File

@ -0,0 +1,46 @@
/**
* 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.cloudstack.config;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.CaseFormat;
/**
* Decides what type of credentials createContext is supplied with.
*
* @author Adrian Cole
*/
public enum CredentialType {
API_ACCESS_KEY_CREDENTIALS,
PASSWORD_CREDENTIALS;
@Override
public String toString() {
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name());
}
public static CredentialType fromValue(String credentialType) {
return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(credentialType,
"credentialType")));
}
}

View File

@ -26,7 +26,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.ListAccountsOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.OnlyElement;
@ -46,7 +46,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface AccountAsyncClient {
/**

View File

@ -27,7 +27,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.functions.ReturnVoidOnNotFoundOr404OrUnableToFindAccountOwner;
import org.jclouds.cloudstack.options.AssociateIPAddressOptions;
import org.jclouds.cloudstack.options.ListPublicIPAddressesOptions;
@ -50,7 +50,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface AddressAsyncClient {

View File

@ -26,7 +26,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.AsyncJob;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.functions.ParseAsyncJobFromHttpResponse;
import org.jclouds.cloudstack.functions.ParseAsyncJobsFromHttpResponse;
import org.jclouds.cloudstack.options.ListAsyncJobsOptions;
@ -47,7 +47,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface AsyncJobAsyncClient {

View File

@ -23,7 +23,7 @@ import javax.ws.rs.GET;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.Capabilities;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
@ -38,7 +38,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface ConfigurationAsyncClient {

View File

@ -21,7 +21,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
@ -43,7 +43,7 @@ import javax.ws.rs.core.MediaType;
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Domain_Admin.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface DomainAccountAsyncClient extends AccountAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Domain;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.ListDomainChildrenOptions;
import org.jclouds.cloudstack.options.ListDomainsOptions;
import org.jclouds.rest.annotations.ExceptionParser;
@ -46,7 +46,7 @@ import java.util.Set;
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Domain_Admin.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface DomainDomainAsyncClient {

View File

@ -24,7 +24,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.binders.ResourceLimitToQueryParams;
import org.jclouds.cloudstack.domain.ResourceLimit;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
@ -41,7 +41,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Domain_Admin.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface DomainLimitAsyncClient extends LimitAsyncClient {
/**

View File

@ -21,7 +21,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.User;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.ListUsersOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
@ -46,7 +46,7 @@ import java.util.Set;
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Domain_Admin.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface DomainUserAsyncClient {

View File

@ -25,7 +25,7 @@ import java.util.Set;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Event;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.functions.ParseEventTypesFromHttpResponse;
import org.jclouds.cloudstack.options.ListEventsOptions;
import org.jclouds.rest.annotations.ExceptionParser;
@ -43,7 +43,7 @@ import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
* @see org.jclouds.cloudstack.features.AccountClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface EventAsyncClient {
/**

View File

@ -28,7 +28,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateFirewallRuleOptions;
import org.jclouds.cloudstack.options.ListFirewallRulesOptions;
import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions;
@ -52,7 +52,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see FirewallClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface FirewallAsyncClient {

View File

@ -24,7 +24,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateAccountOptions;
import org.jclouds.cloudstack.options.UpdateAccountOptions;
import org.jclouds.rest.annotations.ExceptionParser;
@ -44,7 +44,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalAccountAsyncClient extends DomainAccountAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Alert;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.ListAlertsOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
@ -42,7 +42,7 @@ import java.util.Set;
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalAlertAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Capacity;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.ListCapacityOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
@ -42,7 +42,7 @@ import java.util.Set;
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalCapacityAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.ConfigurationEntry;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.ListConfigurationEntriesOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.OnlyElement;
@ -45,7 +45,7 @@ import java.util.Set;
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalConfigurationAsyncClient extends ConfigurationAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Domain;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateDomainOptions;
import org.jclouds.cloudstack.options.UpdateDomainOptions;
import org.jclouds.rest.annotations.ExceptionParser;
@ -44,7 +44,7 @@ import javax.ws.rs.core.MediaType;
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalDomainAsyncClient extends DomainDomainAsyncClient {

View File

@ -21,7 +21,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Cluster;
import org.jclouds.cloudstack.domain.Host;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.AddClusterOptions;
import org.jclouds.cloudstack.options.AddHostOptions;
import org.jclouds.cloudstack.options.AddSecondaryStorageOptions;
@ -50,7 +50,7 @@ import java.util.Set;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html" />
* @author Andrei Savu
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalHostAsyncClient {

View File

@ -26,7 +26,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.DiskOffering;
import org.jclouds.cloudstack.domain.NetworkOffering;
import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateDiskOfferingOptions;
import org.jclouds.cloudstack.options.CreateServiceOfferingOptions;
import org.jclouds.cloudstack.options.UpdateDiskOfferingOptions;
@ -48,7 +48,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html" />
* @author Andrei Savu
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalOfferingAsyncClient extends OfferingAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Pod;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreatePodOptions;
import org.jclouds.cloudstack.options.ListPodsOptions;
import org.jclouds.cloudstack.options.UpdatePodOptions;
@ -48,7 +48,7 @@ import java.util.Set;
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalPodAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.StoragePool;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.ListStoragePoolsOptions;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
@ -40,7 +40,7 @@ import java.util.Set;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html" />
* @author Richard Downer
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
@SkipEncoding({'/'})
public interface GlobalStoragePoolAsyncClient {

View File

@ -21,7 +21,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.JobResult;
import org.jclouds.cloudstack.domain.UsageRecord;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.functions.DateToYyyyMmDd;
import org.jclouds.cloudstack.options.GenerateUsageRecordsOptions;
import org.jclouds.cloudstack.options.ListUsageRecordsOptions;
@ -45,7 +45,7 @@ import java.util.Set;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html" />
* @author Richard Downer
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalUsageAsyncClient {

View File

@ -22,7 +22,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.collections.Integration;
import org.jclouds.cloudstack.domain.ApiKeyPair;
import org.jclouds.cloudstack.domain.User;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateUserOptions;
import org.jclouds.cloudstack.options.UpdateUserOptions;
import org.jclouds.rest.annotations.Endpoint;
@ -46,7 +46,7 @@ import javax.ws.rs.core.MediaType;
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalUserAsyncClient extends DomainUserAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.VlanIPRange;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateVlanIPRangeOptions;
import org.jclouds.cloudstack.options.ListVlanIPRangesOptions;
import org.jclouds.rest.annotations.ExceptionParser;
@ -46,7 +46,7 @@ import java.util.Set;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html" />
* @author Richard Downer
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalVlanAsyncClient {

View File

@ -21,7 +21,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.NetworkType;
import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateZoneOptions;
import org.jclouds.cloudstack.options.UpdateZoneOptions;
import org.jclouds.rest.annotations.ExceptionParser;
@ -45,7 +45,7 @@ import javax.ws.rs.core.MediaType;
* "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalZoneAsyncClient extends ZoneAsyncClient {

View File

@ -27,7 +27,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.OSType;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.functions.ParseIdToNameEntryFromHttpResponse;
import org.jclouds.cloudstack.functions.ParseIdToNameFromHttpResponse;
import org.jclouds.cloudstack.options.ListOSTypesOptions;
@ -50,7 +50,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GuestOSAsyncClient {

View File

@ -23,7 +23,7 @@ import java.util.Set;
import javax.ws.rs.GET;
import javax.ws.rs.QueryParam;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.functions.ParseNamesFromHttpResponse;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
@ -41,7 +41,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface HypervisorAsyncClient {

View File

@ -29,7 +29,7 @@ import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.ExtractMode;
import org.jclouds.cloudstack.domain.ISO;
import org.jclouds.cloudstack.domain.ISOPermissions;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.AccountInDomainOptions;
import org.jclouds.cloudstack.options.DeleteISOOptions;
import org.jclouds.cloudstack.options.ExtractISOOptions;
@ -54,7 +54,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see http://download.cloud.com/releases/2.2.12/api/TOC_User.html
* @author Richard Downer
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
@SkipEncoding({'/', ','})
public interface ISOAsyncClient {

View File

@ -25,7 +25,7 @@ import javax.ws.rs.GET;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.ResourceLimit;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.ListResourceLimitsOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
@ -43,7 +43,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface LimitAsyncClient {
/**

View File

@ -28,7 +28,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.LoadBalancerRule;
import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateLoadBalancerRuleOptions;
import org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions;
import org.jclouds.cloudstack.options.UpdateLoadBalancerRuleOptions;
@ -52,7 +52,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface LoadBalancerAsyncClient {

View File

@ -27,7 +27,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateIPForwardingRuleOptions;
import org.jclouds.cloudstack.options.ListIPForwardingRulesOptions;
import org.jclouds.rest.annotations.ExceptionParser;
@ -51,7 +51,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface NATAsyncClient {

View File

@ -26,7 +26,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateNetworkOptions;
import org.jclouds.cloudstack.options.ListNetworksOptions;
import org.jclouds.rest.annotations.ExceptionParser;
@ -47,7 +47,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface NetworkAsyncClient {

View File

@ -28,7 +28,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.DiskOffering;
import org.jclouds.cloudstack.domain.NetworkOffering;
import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.ListDiskOfferingsOptions;
import org.jclouds.cloudstack.options.ListNetworkOfferingsOptions;
import org.jclouds.cloudstack.options.ListServiceOfferingsOptions;
@ -50,7 +50,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface OfferingAsyncClient {

View File

@ -26,7 +26,7 @@ import java.util.Set;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.SshKeyPair;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.ListSSHKeyPairsOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.OnlyElement;
@ -45,7 +45,7 @@ import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
* href="http://download.cloud.com/releases/2.2.0/api_2.2.8/TOC_User.html"
* />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface SSHKeyPairAsyncClient {
/**

View File

@ -28,7 +28,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.binders.BindAccountSecurityGroupPairsToIndexedQueryParams;
import org.jclouds.cloudstack.binders.BindCIDRsToCommaDelimitedQueryParam;
import org.jclouds.cloudstack.domain.SecurityGroup;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.AccountInDomainOptions;
import org.jclouds.cloudstack.options.ListSecurityGroupsOptions;
import org.jclouds.rest.annotations.BinderParam;
@ -52,7 +52,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface SecurityGroupAsyncClient {

View File

@ -25,7 +25,7 @@ import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.Snapshot;
import org.jclouds.cloudstack.domain.SnapshotPolicy;
import org.jclouds.cloudstack.domain.SnapshotPolicySchedule;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateSnapshotOptions;
import org.jclouds.cloudstack.options.ListSnapshotPoliciesOptions;
import org.jclouds.cloudstack.options.ListSnapshotsOptions;
@ -54,7 +54,7 @@ import java.util.Set;
* @see http://download.cloud.com/releases/2.2.0/api/TOC_User.html
* @author Richard Downer
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface SnapshotAsyncClient {

View File

@ -31,7 +31,7 @@ import org.jclouds.cloudstack.domain.ExtractMode;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.cloudstack.domain.TemplateMetadata;
import org.jclouds.cloudstack.domain.TemplatePermission;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.AccountInDomainOptions;
import org.jclouds.cloudstack.options.CreateTemplateOptions;
import org.jclouds.cloudstack.options.DeleteTemplateOptions;
@ -63,7 +63,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
@SkipEncoding(',')
public interface TemplateAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.VMGroup;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateVMGroupOptions;
import org.jclouds.cloudstack.options.ListVMGroupsOptions;
import org.jclouds.cloudstack.options.UpdateVMGroupOptions;
@ -43,7 +43,7 @@ import java.util.Set;
* @see VMGroupClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface VMGroupAsyncClient {
/**

View File

@ -27,7 +27,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
import org.jclouds.cloudstack.options.ListVirtualMachinesOptions;
import org.jclouds.rest.annotations.ExceptionParser;
@ -49,7 +49,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface VirtualMachineAsyncClient {

View File

@ -27,7 +27,7 @@ import java.util.Set;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.Volume;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.ListVolumesOptions;
import org.jclouds.rest.annotations.*;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
@ -42,7 +42,7 @@ import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
* @see org.jclouds.cloudstack.features.VolumeClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface VolumeAsyncClient {
/**

View File

@ -26,7 +26,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.ListZonesOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.OnlyElement;
@ -46,7 +46,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface ZoneAsyncClient {

View File

@ -11,7 +11,6 @@ import javax.ws.rs.core.UriBuilder;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter;
import com.google.common.base.Supplier;
import com.google.common.net.HttpHeaders;
@ -23,7 +22,7 @@ import com.google.common.net.HttpHeaders;
* />
*/
@Singleton
public class AddSessionKeyAndJSessionIdToRequest implements HttpRequestFilter {
public class AddSessionKeyAndJSessionIdToRequest implements AuthenticationFilter {
private final Supplier<LoginResponse> loginResponseSupplier;
private final Provider<UriBuilder> uriBuilderProvider;

View File

@ -0,0 +1,35 @@
/**
* 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.cloudstack.filters;
import org.jclouds.http.HttpRequestFilter;
import com.google.inject.ImplementedBy;
/**
* Marker interface that determines how we authenticate http requests in cloudstack. default to sign
* requests as opposed to login.
*
* @author Adrian Cole
*
*/
@ImplementedBy(QuerySigner.class)
public interface AuthenticationFilter extends HttpRequestFilter {
}

View File

@ -58,7 +58,7 @@ import com.google.common.collect.Multimap;
*
*/
@Singleton
public class QuerySigner implements HttpRequestFilter, RequestSigner {
public class QuerySigner implements AuthenticationFilter, RequestSigner {
private final SignatureWire signatureWire;
private final String accessKey;

View File

@ -0,0 +1,62 @@
/**
* 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.cloudstack.functions;
import java.io.File;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.cloudstack.features.SessionClient;
import org.jclouds.crypto.CryptoStreams;
import org.jclouds.domain.Credentials;
import com.google.common.base.Function;
@Singleton
public class LoginWithPasswordCredentials implements Function<Credentials, LoginResponse> {
private final SessionClient client;
@Inject
public LoginWithPasswordCredentials(SessionClient client) {
this.client = client;
}
@Override
public LoginResponse apply(Credentials input) {
String username = input.identity;
String domain = "ROOT";
// domain may be present
if (username.indexOf('/') != -1) {
File domainUsername = new File(username);
username = domainUsername.getName();
domain = domainUsername.getParent();
}
String hashedPassword = CryptoStreams.md5Hex(input.credential);
return client.loginUserInDomainWithHashOfPassword(username, domain, hashedPassword);
}
@Override
public String toString() {
return "loginWithPasswordCredentials()";
}
}

View File

@ -0,0 +1,92 @@
/**
* 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.cloudstack.handlers;
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
import static org.jclouds.http.HttpUtils.releasePayload;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.cloudstack.features.SessionClient;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.logging.Logger;
import com.google.common.cache.LoadingCache;
import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
* This will parse and set an appropriate exception on the command object.
*
* @author Adrian Cole
*
*/
@Singleton
public class RetryOnRenewAndLogoutOnClose implements HttpRetryHandler {
@Resource
protected Logger logger = Logger.NULL;
private final LoadingCache<Credentials, LoginResponse> authenticationResponseCache;
private final SessionClient sessionClient;
@Inject
protected RetryOnRenewAndLogoutOnClose(LoadingCache<Credentials, LoginResponse> authenticationResponseCache,
SessionClient sessionClient) {
this.authenticationResponseCache = authenticationResponseCache;
this.sessionClient = sessionClient;
}
@Override
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
boolean retry = false; // default
try {
switch (response.getStatusCode()) {
case 401:
byte[] content = closeClientButKeepContentStream(response);
if (new String(content).equals("TODO: What state can we retry?")) {
logger.debug("invalidating session");
authenticationResponseCache.invalidateAll();
retry = true;
}
}
return retry;
} finally {
releasePayload(response);
}
}
/**
* it is important that we close any sessions on close to help the server not become overloaded.
*/
@PreDestroy
public void logoutOnClose() {
for (LoginResponse s : authenticationResponseCache.asMap().values()) {
try {
sessionClient.logoutUser(s.getSessionKey());
} catch (Exception e) {
logger.error(e, "error logging out session %s", s.getSessionKey());
}
}
}
}

View File

@ -0,0 +1,87 @@
/**
* 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.cloudstack;
import static org.testng.Assert.assertNotNull;
import java.net.URI;
import java.net.URLEncoder;
import java.util.Properties;
import org.jclouds.cloudstack.features.AccountClient;
import org.jclouds.cloudstack.features.BaseCloudStackRestClientExpectTest;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.net.HttpHeaders;
/**
*
* @see KeystoneProperties#CREDENTIAL_TYPE
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "PasswordAuthenticationExpectTest")
public class PasswordAuthenticationExpectTest extends BaseCloudStackRestClientExpectTest<CloudStackContext> {
/**
* this reflects the properties that a user would pass to createContext
*/
@Override
protected Properties setupProperties() {
Properties contextProperties = super.setupProperties();
contextProperties.setProperty("jclouds.cloudstack.credential-type", "passwordCredentials");
return contextProperties;
}
@SuppressWarnings("deprecation")
public void testLoginWithPasswordSetsSessionKeyAndCookie() {
CloudStackContext context = requestsSendResponses(
loginRequest, loginResponse,
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&command=listAccounts&sessionkey=" + URLEncoder.encode(sessionKey)))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.put(HttpHeaders.COOKIE, "JSESSIONID=" + jSessionId)
.build())
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/listaccountsresponse.json"))
.build()
, logoutRequest, logoutResponse);
AccountClient client = context.getProviderSpecificContext().getApi().getAccountClient();
assertNotNull(client.listAccounts());
context.close();
}
@Override
protected CloudStackContext clientFrom(CloudStackContext context) {
return context;
}
}

View File

@ -18,6 +18,10 @@
*/
package org.jclouds.cloudstack.features;
import static org.jclouds.crypto.CryptoStreams.md5Hex;
import java.net.URI;
import java.net.URLEncoder;
import java.util.Properties;
import org.jclouds.cloudstack.CloudStackContext;
@ -28,6 +32,7 @@ import org.jclouds.logging.config.NullLoggingModule;
import org.jclouds.rest.BaseRestClientExpectTest;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
@ -51,4 +56,37 @@ public abstract class BaseCloudStackRestClientExpectTest<S> extends BaseRestClie
protected abstract S clientFrom(CloudStackContext context);
protected final HttpRequest loginRequest = HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&command=login&" +
"username=identity&password=" + md5Hex("credential")+ "&domain=ROOT"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build();
protected final String jSessionId = "90DD65D13AEAA590ECCA312D150B9F6D";
protected final String sessionKey = "uYT4/MNiglgAKiZRQkvV8QP8gn0=";
protected final HttpResponse loginResponse = HttpResponse.builder()
.statusCode(200)
.headers(
ImmutableMultimap.<String, String>builder()
.put("Set-Cookie", "JSESSIONID="+jSessionId+"; Path=/client")
.build())
.payload(payloadFromResource("/loginresponse.json"))
.build();
@SuppressWarnings("deprecation")
protected final HttpRequest logoutRequest = HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&command=logout&" +
"sessionkey=" + URLEncoder.encode(sessionKey)))
.build();
protected final HttpResponse logoutResponse = HttpResponse.builder().statusCode(200).build();
}

View File

@ -0,0 +1,65 @@
/**
* 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.cloudstack.handlers;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.testng.Assert.assertTrue;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.cloudstack.features.SessionClient;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payloads;
import org.testng.annotations.Test;
import com.google.common.cache.LoadingCache;
/**
* Tests behavior of {@code RetryOnRenewAndLogoutOnClose} handler
*
* @author grkvlt@apache.org
*/
@Test(groups = "unit", testName = "RetryOnRenewAndLogoutOnCloseTest")
public class RetryOnRenewAndLogoutOnCloseTest {
@SuppressWarnings("unchecked")
@Test
public void test401ShouldRetry() {
HttpCommand command = createMock(HttpCommand.class);
SessionClient sessionClient = createMock(SessionClient.class);
LoadingCache<Credentials, LoginResponse> cache = createMock(LoadingCache.class);
cache.invalidateAll();
expectLastCall();
replay(cache, command);
HttpResponse response = HttpResponse.builder().payload(
Payloads.newStringPayload("TODO: What state can we retry?")).statusCode(401).build();
RetryOnRenewAndLogoutOnClose retry = new RetryOnRenewAndLogoutOnClose(cache, sessionClient);
assertTrue(retry.shouldRetryRequest(command, response));
verify(cache, command);
}
}