Merged latest jclouds master branch

This commit is contained in:
Jeremy Daggett 2012-02-02 13:25:17 -08:00
commit 50cf37f722
429 changed files with 10453 additions and 5176 deletions

View File

@ -25,14 +25,26 @@ import javax.inject.Singleton;
import org.jclouds.cloudfiles.CDNManagement; import org.jclouds.cloudfiles.CDNManagement;
import org.jclouds.cloudfiles.CloudFilesAsyncClient; import org.jclouds.cloudfiles.CloudFilesAsyncClient;
import org.jclouds.cloudfiles.CloudFilesClient; import org.jclouds.cloudfiles.CloudFilesClient;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse; import org.jclouds.http.annotation.ClientError;
import org.jclouds.openstack.reference.AuthHeaders; 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.openstack.keystone.v1_1.config.AuthenticationServiceModule;
import org.jclouds.openstack.keystone.v1_1.domain.Auth;
import org.jclouds.openstack.keystone.v1_1.handlers.RetryOnRenew;
import org.jclouds.openstack.swift.CommonSwiftAsyncClient; import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
import org.jclouds.openstack.swift.CommonSwiftClient; import org.jclouds.openstack.swift.CommonSwiftClient;
import org.jclouds.openstack.swift.config.BaseSwiftRestClientModule; import org.jclouds.openstack.swift.Storage;
import org.jclouds.openstack.swift.config.SwiftObjectModule;
import org.jclouds.openstack.swift.handlers.ParseSwiftErrorFromHttpResponse;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
import com.google.common.collect.Iterables;
import com.google.inject.Provides; import com.google.inject.Provides;
/** /**
@ -41,10 +53,16 @@ import com.google.inject.Provides;
*/ */
@ConfiguresRestClient @ConfiguresRestClient
@RequiresHttp @RequiresHttp
public class CloudFilesRestClientModule extends BaseSwiftRestClientModule<CloudFilesClient, CloudFilesAsyncClient> { public class CloudFilesRestClientModule extends RestClientModule<CloudFilesClient, CloudFilesAsyncClient> {
private final AuthenticationServiceModule module;
public CloudFilesRestClientModule(AuthenticationServiceModule module) {
super(CloudFilesClient.class, CloudFilesAsyncClient.class);
this.module = module;
}
public CloudFilesRestClientModule() { public CloudFilesRestClientModule() {
super(CloudFilesClient.class, CloudFilesAsyncClient.class); this(new AuthenticationServiceModule());
} }
@Provides @Provides
@ -62,7 +80,36 @@ public class CloudFilesRestClientModule extends BaseSwiftRestClientModule<CloudF
@Provides @Provides
@Singleton @Singleton
@CDNManagement @CDNManagement
protected URI provideCDNUrl(AuthenticationResponse response) { protected URI provideCDNUrl(Auth response) {
return response.getServices().get(AuthHeaders.CDN_MANAGEMENT_URL); return Iterables.get(response.getServiceCatalog().get("cloudFilesCDN"), 0).getPublicURL();
} }
@Provides
@Singleton
@Storage
protected URI provideStorageUrl(Auth response) {
return Iterables.get(response.getServiceCatalog().get("cloudFiles"), 0).getPublicURL();
}
@Override
protected void configure() {
install(module);
install(new SwiftObjectModule());
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
super.configure();
}
@Override
protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseSwiftErrorFromHttpResponse.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseSwiftErrorFromHttpResponse.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseSwiftErrorFromHttpResponse.class);
}
@Override
protected void bindRetryHandlers() {
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
}
} }

View File

@ -34,7 +34,6 @@ public class CloudLoadBalancersPropertiesBuilder extends PropertiesBuilder {
protected Properties defaultProperties() { protected Properties defaultProperties() {
Properties properties = super.defaultProperties(); Properties properties = super.defaultProperties();
properties.setProperty(PROPERTY_API_VERSION, "1.0"); properties.setProperty(PROPERTY_API_VERSION, "1.0");
return properties; return properties;
} }

View File

@ -27,6 +27,7 @@ import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient; import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient; import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient;
@ -50,18 +51,17 @@ import org.jclouds.location.Provider;
import org.jclouds.location.Region; import org.jclouds.location.Region;
import org.jclouds.location.config.ProvideRegionToURIViaProperties; import org.jclouds.location.config.ProvideRegionToURIViaProperties;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse; import org.jclouds.openstack.keystone.v1_1.config.AuthenticationServiceModule;
import org.jclouds.openstack.config.OpenStackAuthenticationModule; import org.jclouds.openstack.keystone.v1_1.domain.Auth;
import org.jclouds.openstack.handlers.RetryOnRenew; import org.jclouds.openstack.keystone.v1_1.handlers.RetryOnRenew;
import org.jclouds.openstack.reference.AuthHeaders;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
import com.google.common.base.Supplier; import com.google.common.base.Function;
import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap; import com.google.common.collect.Maps;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.Scopes; import com.google.inject.Scopes;
@ -83,23 +83,44 @@ public class CloudLoadBalancersRestClientModule extends
.put(NodeClient.class, NodeAsyncClient.class)// .put(NodeClient.class, NodeAsyncClient.class)//
.build(); .build();
public CloudLoadBalancersRestClientModule() { private final AuthenticationServiceModule module;
public CloudLoadBalancersRestClientModule(AuthenticationServiceModule module) {
super(CloudLoadBalancersClient.class, CloudLoadBalancersAsyncClient.class, DELEGATE_MAP); super(CloudLoadBalancersClient.class, CloudLoadBalancersAsyncClient.class, DELEGATE_MAP);
this.module = module;
} }
public CloudLoadBalancersRestClientModule() {
this(new AuthenticationServiceModule());
}
protected void bindRegionsToProvider() { protected void bindRegionsToProvider() {
bindRegionsToProvider(ProvideRegionToURIViaPropertiesWithAccountID.class); bindRegionsToProvider(RegionUrisFromPropertiesAndAccountIDPathSuffix.class);
} }
@Singleton @Singleton
public static class ProvideRegionToURIViaPropertiesWithAccountID extends ProvideRegionToURIViaProperties { public static class RegionUrisFromPropertiesAndAccountIDPathSuffix extends ProvideRegionToURIViaProperties {
private final String accountID;
private final javax.inject.Provider<UriBuilder> builders;
@Inject @Inject
protected ProvideRegionToURIViaPropertiesWithAccountID(Injector injector, protected RegionUrisFromPropertiesAndAccountIDPathSuffix(Injector injector,
@Named("CONSTANTS") Multimap<String, String> constants, javax.inject.Provider<UriBuilder> builders, @Named(RackspaceConstants.PROPERTY_ACCOUNT_ID) String accountID) {
@Named(RackspaceConstants.PROPERTY_ACCOUNT_ID) String accountID) { super(injector);
super(injector, constants); this.builders = builders;
constants.replaceValues(RackspaceConstants.PROPERTY_ACCOUNT_ID, ImmutableSet.of(accountID)); this.accountID = accountID;
}
@Override
public Map<String, URI> get() {
return Maps.transformValues(super.get(), new Function<URI, URI>(){
@Override
public URI apply(URI input) {
return builders.get().uri(input).path(accountID).build();
}
});
} }
} }
@ -110,7 +131,7 @@ public class CloudLoadBalancersRestClientModule extends
@Override @Override
protected void configure() { protected void configure() {
install(new OpenStackAuthenticationModule()); install(module);
bind(DateAdapter.class).to(Iso8601DateAdapter.class); bind(DateAdapter.class).to(Iso8601DateAdapter.class);
bindRegionsToProvider(); bindRegionsToProvider();
install(new FactoryModuleBuilder().build(ConvertLB.Factory.class)); install(new FactoryModuleBuilder().build(ConvertLB.Factory.class));
@ -120,8 +141,8 @@ public class CloudLoadBalancersRestClientModule extends
@Provides @Provides
@Singleton @Singleton
@Named(RackspaceConstants.PROPERTY_ACCOUNT_ID) @Named(RackspaceConstants.PROPERTY_ACCOUNT_ID)
protected String accountID(Supplier<AuthenticationResponse> in) { protected String accountID(Auth response) {
URI serverURL = in.get().getServices().get(AuthHeaders.SERVER_MANAGEMENT_URL); URI serverURL = Iterables.get(response.getServiceCatalog().get("cloudServers"), 0).getPublicURL();
return serverURL.getPath().substring(serverURL.getPath().lastIndexOf('/') + 1); return serverURL.getPath().substring(serverURL.getPath().lastIndexOf('/') + 1);
} }

View File

@ -18,22 +18,11 @@
*/ */
package org.jclouds.cloudloadbalancers; package org.jclouds.cloudloadbalancers;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.cloudloadbalancers.reference.RackspaceConstants.PROPERTY_ACCOUNT_ID;
import static org.jclouds.cloudloadbalancers.reference.Region.DFW;
import static org.jclouds.location.reference.LocationConstants.ENDPOINT;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.io.IOException; import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import org.jclouds.cloudloadbalancers.features.BaseCloudLoadBalancersAsyncClientTest; import org.jclouds.cloudloadbalancers.internal.BaseCloudLoadBalancersAsyncClientTest;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -53,11 +42,11 @@ public class CloudLoadBalancersAsyncClientTest extends BaseCloudLoadBalancersAsy
private CloudLoadBalancersClient syncClient; private CloudLoadBalancersClient syncClient;
public void testSync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException { public void testSync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException {
assert syncClient.getLoadBalancerClient("DFW") != null; assert syncClient.getLoadBalancerClient("LON") != null;
} }
public void testAsync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException { public void testAsync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException {
assert asyncClient.getLoadBalancerClient("DFW") != null; assert asyncClient.getLoadBalancerClient("LON") != null;
} }
@Override @Override
@ -79,23 +68,4 @@ public class CloudLoadBalancersAsyncClientTest extends BaseCloudLoadBalancersAsy
} }
protected String provider = "cloudloadbalancers";
@Override
public RestContextSpec<CloudLoadBalancersClient, CloudLoadBalancersAsyncClient> createContextSpec() {
return new RestContextFactory(getProperties()).createContextSpec(provider, "user", "password", new Properties());
}
@Override
protected Properties getProperties() {
Properties overrides = new Properties();
overrides.setProperty(PROPERTY_ENDPOINT, "https://auth.api.rackspacecloud.com");
overrides.setProperty(PROPERTY_API_VERSION, "1");
overrides.setProperty(PROPERTY_REGIONS, "DFW");
overrides.setProperty(PROPERTY_REGION + "." + DFW + "." + ENDPOINT, String
.format("https://dfw.loadbalancers.api.rackspacecloud.com/v{%s}/{%s}", PROPERTY_API_VERSION,
PROPERTY_ACCOUNT_ID));
overrides.setProperty(provider + ".contextbuilder", CloudLoadBalancersContextBuilder.class.getName());
return overrides;
}
} }

View File

@ -1,148 +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.cloudloadbalancers.features;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.URI;
import java.util.Map;
import java.util.Properties;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient;
import org.jclouds.cloudloadbalancers.config.CloudLoadBalancersRestClientModule;
import org.jclouds.cloudloadbalancers.functions.ConvertLB;
import org.jclouds.cloudloadbalancers.reference.Region;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
import org.jclouds.internal.ClassMethodArgs;
import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
import org.jclouds.rest.internal.RestContextImpl;
import org.testng.annotations.BeforeClass;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.base.Throwables;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Module;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.google.inject.util.Types;
/**
* @author Adrian Cole
*/
public abstract class BaseCloudLoadBalancersAsyncClientTest<T> extends RestClientTest<T> {
@RequiresHttp
@ConfiguresRestClient
public static class CloudLoadBalancersRestClientModuleExtension extends CloudLoadBalancersRestClientModule {
protected void bindRegionsToProvider() {
bindRegionsToProvider(Regions.class);
}
//TODO: replace this with Expect test
@SuppressWarnings("unchecked")
@Override
protected void configure() {
// following from CloudLoadBalancersRestClientModule, except we are hard-coding the auth response
install(new OpenStackAuthenticationModule() {
@Override
protected Supplier<AuthenticationResponse> provideAuthenticationResponseSupplier(
LoadingCache<Credentials, AuthenticationResponse> cache, Credentials in) {
return Suppliers.ofInstance(new AuthenticationResponse("token", ImmutableMap.<String, URI> of()));
}
});
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
bindRegionsToProvider();
install(new FactoryModuleBuilder().build(ConvertLB.Factory.class));
// following from RestClientModule
bind(new TypeLiteral<RestContext>() {
}).to(
(TypeLiteral) TypeLiteral.get(Types.newParameterizedType(
RestContextImpl.class, syncClientType, asyncClientType))).in(
Scopes.SINGLETON);
bind(TypeLiteral.get(Types.newParameterizedType(RestContext.class, syncClientType, asyncClientType))).to(
(TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class, syncClientType,
asyncClientType))).in(Scopes.SINGLETON);
bindAsyncClient();
bindClient();
bindErrorHandlers();
bindRetryHandlers();
}
static class Regions implements javax.inject.Provider<Map<String, URI>> {
@Override
public Map<String, URI> get() {
return ImmutableMap.<String, URI> of("DFW", URI
.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234"));
}
}
@Override
protected String accountID(Supplier<AuthenticationResponse> in) {
return "1234";
}
}
@Override
protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 1);
assertEquals(request.getFilters().get(0).getClass(), AuthenticateRequest.class);
}
@Override
protected Module createModule() {
return new CloudLoadBalancersRestClientModuleExtension();
}
@Override
public RestContextSpec<CloudLoadBalancersClient, CloudLoadBalancersAsyncClient> createContextSpec() {
Properties props = new Properties();
return new RestContextFactory().createContextSpec("cloudloadbalancers", "email", "apikey", props);
}
@BeforeClass
@Override
protected void setupFactory() throws IOException {
super.setupFactory();
try {
processor.setCaller(new ClassMethodArgs(CloudLoadBalancersAsyncClient.class,
CloudLoadBalancersAsyncClient.class.getMethod("getLoadBalancerClient", String.class),
new Object[] { Region.DFW }));
} catch (Exception e) {
Throwables.propagate(e);
}
}
}

View File

@ -18,26 +18,18 @@
*/ */
package org.jclouds.cloudloadbalancers.features; package org.jclouds.cloudloadbalancers.features;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Properties;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersContextBuilder;
import org.jclouds.cloudloadbalancers.domain.LoadBalancerAttributes; import org.jclouds.cloudloadbalancers.domain.LoadBalancerAttributes;
import org.jclouds.cloudloadbalancers.domain.LoadBalancerRequest;
import org.jclouds.cloudloadbalancers.domain.LoadBalancerAttributes.Builder; import org.jclouds.cloudloadbalancers.domain.LoadBalancerAttributes.Builder;
import org.jclouds.cloudloadbalancers.domain.LoadBalancerRequest;
import org.jclouds.cloudloadbalancers.domain.VirtualIP.Type; import org.jclouds.cloudloadbalancers.domain.VirtualIP.Type;
import org.jclouds.cloudloadbalancers.functions.UnwrapLoadBalancer; import org.jclouds.cloudloadbalancers.functions.UnwrapLoadBalancer;
import org.jclouds.cloudloadbalancers.functions.UnwrapLoadBalancers; import org.jclouds.cloudloadbalancers.functions.UnwrapLoadBalancers;
import org.jclouds.cloudloadbalancers.internal.BaseCloudLoadBalancersAsyncClientTest;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions; import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
@ -61,7 +53,7 @@ public class LoadBalancerAsyncClientTest extends BaseCloudLoadBalancersAsyncClie
HttpRequest httpRequest = processor.createRequest(method); HttpRequest httpRequest = processor.createRequest(method);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers HTTP/1.1"); "GET https://lon.loadbalancers.api.rackspacecloud.com/v1.0/10001786/loadbalancers HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false); assertPayloadEquals(httpRequest, null, null, false);
@ -78,7 +70,7 @@ public class LoadBalancerAsyncClientTest extends BaseCloudLoadBalancersAsyncClie
HttpRequest httpRequest = processor.createRequest(method, 5); HttpRequest httpRequest = processor.createRequest(method, 5);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/5 HTTP/1.1"); "GET https://lon.loadbalancers.api.rackspacecloud.com/v1.0/10001786/loadbalancers/5 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false); assertPayloadEquals(httpRequest, null, null, false);
@ -96,7 +88,7 @@ public class LoadBalancerAsyncClientTest extends BaseCloudLoadBalancersAsyncClie
"HTTP").port(80).virtualIPType(Type.PUBLIC).build()); "HTTP").port(80).virtualIPType(Type.PUBLIC).build());
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"POST https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers HTTP/1.1"); "POST https://lon.loadbalancers.api.rackspacecloud.com/v1.0/10001786/loadbalancers HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals( assertPayloadEquals(
httpRequest, httpRequest,
@ -117,7 +109,7 @@ public class LoadBalancerAsyncClientTest extends BaseCloudLoadBalancersAsyncClie
"HTTP").port(80).virtualIPId(4).build()); "HTTP").port(80).virtualIPId(4).build());
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"POST https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers HTTP/1.1"); "POST https://lon.loadbalancers.api.rackspacecloud.com/v1.0/10001786/loadbalancers HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals( assertPayloadEquals(
httpRequest, httpRequest,
@ -138,7 +130,7 @@ public class LoadBalancerAsyncClientTest extends BaseCloudLoadBalancersAsyncClie
HttpRequest httpRequest = processor.createRequest(method, 2, Builder.name("foo")); HttpRequest httpRequest = processor.createRequest(method, 2, Builder.name("foo"));
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"PUT https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/2 HTTP/1.1"); "PUT https://lon.loadbalancers.api.rackspacecloud.com/v1.0/10001786/loadbalancers/2 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, "{\"loadBalancer\":{\"name\":\"foo\"}}", "application/json", false); assertPayloadEquals(httpRequest, "{\"loadBalancer\":{\"name\":\"foo\"}}", "application/json", false);
@ -155,7 +147,7 @@ public class LoadBalancerAsyncClientTest extends BaseCloudLoadBalancersAsyncClie
HttpRequest httpRequest = processor.createRequest(method, 5); HttpRequest httpRequest = processor.createRequest(method, 5);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"DELETE https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/5 HTTP/1.1"); "DELETE https://lon.loadbalancers.api.rackspacecloud.com/v1.0/10001786/loadbalancers/5 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: */*\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: */*\n");
assertPayloadEquals(httpRequest, null, null, false); assertPayloadEquals(httpRequest, null, null, false);
@ -173,20 +165,4 @@ public class LoadBalancerAsyncClientTest extends BaseCloudLoadBalancersAsyncClie
}; };
} }
protected String provider = "cloudloadbalancers";
@Override
public RestContextSpec<CloudLoadBalancersClient, CloudLoadBalancersAsyncClient> createContextSpec() {
return new RestContextFactory(getProperties()).createContextSpec(provider, "user", "password", new Properties());
}
@Override
protected Properties getProperties() {
Properties overrides = new Properties();
overrides.setProperty(PROPERTY_REGIONS, "US");
overrides.setProperty(PROPERTY_API_VERSION, "1");
overrides.setProperty(provider + ".endpoint", "https://auth");
overrides.setProperty(provider + ".contextbuilder", CloudLoadBalancersContextBuilder.class.getName());
return overrides;
}
} }

View File

@ -30,6 +30,7 @@ import org.jclouds.cloudloadbalancers.domain.LoadBalancerAttributes;
import org.jclouds.cloudloadbalancers.domain.LoadBalancerRequest; import org.jclouds.cloudloadbalancers.domain.LoadBalancerRequest;
import org.jclouds.cloudloadbalancers.domain.NodeRequest; import org.jclouds.cloudloadbalancers.domain.NodeRequest;
import org.jclouds.cloudloadbalancers.domain.VirtualIP.Type; import org.jclouds.cloudloadbalancers.domain.VirtualIP.Type;
import org.jclouds.cloudloadbalancers.internal.BaseCloudLoadBalancersClientLiveTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;

View File

@ -18,27 +18,19 @@
*/ */
package org.jclouds.cloudloadbalancers.features; package org.jclouds.cloudloadbalancers.features;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collections; import java.util.Collections;
import java.util.Properties;
import java.util.Set; import java.util.Set;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersContextBuilder;
import org.jclouds.cloudloadbalancers.domain.NodeAttributes; import org.jclouds.cloudloadbalancers.domain.NodeAttributes;
import org.jclouds.cloudloadbalancers.domain.NodeAttributes.Builder; import org.jclouds.cloudloadbalancers.domain.NodeAttributes.Builder;
import org.jclouds.cloudloadbalancers.domain.NodeRequest; import org.jclouds.cloudloadbalancers.domain.NodeRequest;
import org.jclouds.cloudloadbalancers.domain.internal.BaseNode.Condition; import org.jclouds.cloudloadbalancers.domain.internal.BaseNode.Condition;
import org.jclouds.cloudloadbalancers.internal.BaseCloudLoadBalancersAsyncClientTest;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseFirstJsonValueNamed; import org.jclouds.http.functions.ParseFirstJsonValueNamed;
import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions; import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
@ -62,7 +54,7 @@ public class NodeAsyncClientTest extends BaseCloudLoadBalancersAsyncClientTest<N
HttpRequest httpRequest = processor.createRequest(method, 2); HttpRequest httpRequest = processor.createRequest(method, 2);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/2/nodes HTTP/1.1"); "GET https://lon.loadbalancers.api.rackspacecloud.com/v1.0/10001786/loadbalancers/2/nodes HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false); assertPayloadEquals(httpRequest, null, null, false);
@ -79,7 +71,7 @@ public class NodeAsyncClientTest extends BaseCloudLoadBalancersAsyncClientTest<N
HttpRequest httpRequest = processor.createRequest(method, 3, 2); HttpRequest httpRequest = processor.createRequest(method, 3, 2);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/2/nodes/3 HTTP/1.1"); "GET https://lon.loadbalancers.api.rackspacecloud.com/v1.0/10001786/loadbalancers/2/nodes/3 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false); assertPayloadEquals(httpRequest, null, null, false);
@ -97,7 +89,7 @@ public class NodeAsyncClientTest extends BaseCloudLoadBalancersAsyncClientTest<N
address("192.168.1.1").port(8080).build()), 3); address("192.168.1.1").port(8080).build()), 3);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"POST https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/3/nodes HTTP/1.1"); "POST https://lon.loadbalancers.api.rackspacecloud.com/v1.0/10001786/loadbalancers/3/nodes HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals( assertPayloadEquals(
httpRequest, httpRequest,
@ -118,7 +110,7 @@ public class NodeAsyncClientTest extends BaseCloudLoadBalancersAsyncClientTest<N
HttpRequest httpRequest = processor.createRequest(method, Builder.condition(Condition.DISABLED).weight(13), 8, 7); HttpRequest httpRequest = processor.createRequest(method, Builder.condition(Condition.DISABLED).weight(13), 8, 7);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"PUT https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/7/nodes/8 HTTP/1.1"); "PUT https://lon.loadbalancers.api.rackspacecloud.com/v1.0/10001786/loadbalancers/7/nodes/8 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, "{\"node\":{\"condition\":\"DISABLED\",\"weight\":13}}", "application/json", false); assertPayloadEquals(httpRequest, "{\"node\":{\"condition\":\"DISABLED\",\"weight\":13}}", "application/json", false);
@ -135,7 +127,7 @@ public class NodeAsyncClientTest extends BaseCloudLoadBalancersAsyncClientTest<N
HttpRequest httpRequest = processor.createRequest(method, 9, 4); HttpRequest httpRequest = processor.createRequest(method, 9, 4);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"DELETE https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/4/nodes/9 HTTP/1.1"); "DELETE https://lon.loadbalancers.api.rackspacecloud.com/v1.0/10001786/loadbalancers/4/nodes/9 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: */*\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: */*\n");
assertPayloadEquals(httpRequest, null, null, false); assertPayloadEquals(httpRequest, null, null, false);
@ -153,20 +145,4 @@ public class NodeAsyncClientTest extends BaseCloudLoadBalancersAsyncClientTest<N
}; };
} }
protected String provider = "cloudloadbalancers";
@Override
public RestContextSpec<CloudLoadBalancersClient, CloudLoadBalancersAsyncClient> createContextSpec() {
return new RestContextFactory(getProperties()).createContextSpec(provider, "user", "password", new Properties());
}
@Override
protected Properties getProperties() {
Properties overrides = new Properties();
overrides.setProperty(PROPERTY_REGIONS, "US");
overrides.setProperty(PROPERTY_API_VERSION, "1");
overrides.setProperty(provider + ".endpoint", "https://auth");
overrides.setProperty(provider + ".contextbuilder", CloudLoadBalancersContextBuilder.class.getName());
return overrides;
}
} }

View File

@ -37,6 +37,7 @@ import org.jclouds.cloudloadbalancers.domain.NodeAttributes;
import org.jclouds.cloudloadbalancers.domain.NodeRequest; import org.jclouds.cloudloadbalancers.domain.NodeRequest;
import org.jclouds.cloudloadbalancers.domain.LoadBalancer.Status; import org.jclouds.cloudloadbalancers.domain.LoadBalancer.Status;
import org.jclouds.cloudloadbalancers.domain.VirtualIP.Type; import org.jclouds.cloudloadbalancers.domain.VirtualIP.Type;
import org.jclouds.cloudloadbalancers.internal.BaseCloudLoadBalancersClientLiveTest;
import org.testng.annotations.AfterGroups; import org.testng.annotations.AfterGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;

View File

@ -0,0 +1,138 @@
/**
* 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.cloudloadbalancers.internal;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.cloudloadbalancers.reference.Region.LON;
import static org.jclouds.location.reference.LocationConstants.ENDPOINT;
import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import javax.inject.Singleton;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersContextBuilder;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersPropertiesBuilder;
import org.jclouds.cloudloadbalancers.config.CloudLoadBalancersRestClientModule;
import org.jclouds.cloudloadbalancers.features.LoadBalancerAsyncClient;
import org.jclouds.cloudloadbalancers.features.LoadBalancerClient;
import org.jclouds.cloudloadbalancers.reference.Region;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
import org.jclouds.internal.ClassMethodArgs;
import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.openstack.keystone.v1_1.config.AuthenticationServiceModule;
import org.jclouds.openstack.keystone.v1_1.config.AuthenticationServiceModule.GetAuth;
import org.jclouds.openstack.keystone.v1_1.domain.Auth;
import org.jclouds.openstack.keystone.v1_1.parse.ParseAuthTest;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
import org.testng.annotations.BeforeClass;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
import com.google.inject.Provides;
/**
* @author Adrian Cole
*/
public abstract class BaseCloudLoadBalancersAsyncClientTest<T> extends RestClientTest<T> {
protected String provider;
public BaseCloudLoadBalancersAsyncClientTest() {
this.provider = "cloudloadbalancers";
}
@Override
protected Module createModule() {
return new TestCloudLoadBalancersRestClientModule();
}
@ConfiguresRestClient
@RequiresHttp
protected static class TestCloudLoadBalancersRestClientModule extends CloudLoadBalancersRestClientModule {
private TestCloudLoadBalancersRestClientModule() {
super(new AuthenticationServiceModule());
}
@Provides
@Singleton
GetAuth provideGetAuth() {
return new GetAuth(null) {
@Override
public Auth apply(Credentials in) {
return new ParseAuthTest().expected();
}
};
}
}
@Override
protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 1);
assertEquals(request.getFilters().get(0).getClass(), AuthenticateRequest.class);
}
@BeforeClass
@Override
protected void setupFactory() throws IOException {
super.setupFactory();
try {
processor.setCaller(new ClassMethodArgs(CloudLoadBalancersAsyncClient.class,
CloudLoadBalancersAsyncClient.class.getMethod("getLoadBalancerClient", String.class),
new Object[] { Region.LON }));
} catch (Exception e) {
Throwables.propagate(e);
}
}
@Override
protected Properties setupProperties() {
Properties overrides = new Properties();
overrides.setProperty(provider + ".endpoint", "https://auth");
overrides.setProperty(PROPERTY_REGIONS, LON);
overrides.setProperty(PROPERTY_REGION + "." + LON + "." + ISO3166_CODES, "GB-SLG");
overrides.setProperty(PROPERTY_REGION + "." + LON + "." + ENDPOINT,
String.format("https://lon.loadbalancers.api.rackspacecloud.com/v${%s}", PROPERTY_API_VERSION));
return overrides;
}
/**
* this is only here as "cloudloadbalancers" is not in rest.properties
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public RestContextSpec<?, ?> createContextSpec() {
return RestContextFactory.<LoadBalancerClient, LoadBalancerAsyncClient> contextSpec(provider, "https://auth",
"1.0", "", "", "identity", "credential", LoadBalancerClient.class, LoadBalancerAsyncClient.class,
(Class)CloudLoadBalancersPropertiesBuilder.class, (Class)CloudLoadBalancersContextBuilder.class,
ImmutableSet.<Module> of());
}
}

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.cloudloadbalancers.features; package org.jclouds.cloudloadbalancers.internal;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;

View File

@ -47,6 +47,7 @@ import org.jclouds.cloudservers.options.RebuildServerOptions;
import org.jclouds.http.functions.ReturnFalseOn404; import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.openstack.filters.AddTimestampQuery; import org.jclouds.openstack.filters.AddTimestampQuery;
import org.jclouds.openstack.filters.AuthenticateRequest; import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.openstack.services.Compute;
import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint; import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
@ -77,7 +78,7 @@ import com.google.common.util.concurrent.ListenableFuture;
*/ */
@SkipEncoding({ '/', '=' }) @SkipEncoding({ '/', '=' })
@RequestFilters({ AuthenticateRequest.class, AddTimestampQuery.class }) @RequestFilters({ AuthenticateRequest.class, AddTimestampQuery.class })
@Endpoint(ServerManagement.class) @Endpoint(Compute.class)
public interface CloudServersAsyncClient { public interface CloudServersAsyncClient {
/** /**

View File

@ -36,7 +36,7 @@ import com.google.common.collect.ImmutableList;
@Singleton @Singleton
public class FlavorToHardware implements Function<Flavor, Hardware> { public class FlavorToHardware implements Function<Flavor, Hardware> {
public Hardware apply(Flavor from) { public Hardware apply(Flavor from) {
return new HardwareBuilder().ids(from.getId() + "").name(from.getName()) return new HardwareBuilder().ids(from.getId() + "").name(from.getName()).hypervisor("xen")
.processors(ImmutableList.of(new Processor(from.getDisk() / 10.0, 1.0))).ram(from.getRam()) .processors(ImmutableList.of(new Processor(from.getDisk() / 10.0, 1.0))).ram(from.getRam())
.volumes(ImmutableList.<Volume> of(new VolumeImpl((float) from.getDisk(), true, true))).build(); .volumes(ImmutableList.<Volume> of(new VolumeImpl((float) from.getDisk(), true, true))).build();
} }

View File

@ -18,14 +18,18 @@
*/ */
package org.jclouds.cloudservers.config; package org.jclouds.cloudservers.config;
import static com.google.common.base.Suppliers.memoizeWithExpiration;
import java.net.URI; import java.net.URI;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.cloudservers.CloudServersAsyncClient; import org.jclouds.cloudservers.CloudServersAsyncClient;
import org.jclouds.cloudservers.CloudServersClient; import org.jclouds.cloudservers.CloudServersClient;
import org.jclouds.cloudservers.ServerManagement;
import org.jclouds.cloudservers.handlers.ParseCloudServersErrorFromHttpResponse; import org.jclouds.cloudservers.handlers.ParseCloudServersErrorFromHttpResponse;
import org.jclouds.date.TimeStamp;
import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler; import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
@ -34,13 +38,15 @@ import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError; import org.jclouds.http.annotation.ServerError;
import org.jclouds.json.config.GsonModule.DateAdapter; import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse; import org.jclouds.openstack.keystone.v1_1.config.AuthenticationServiceModule;
import org.jclouds.openstack.config.OpenStackAuthenticationModule; import org.jclouds.openstack.keystone.v1_1.domain.Auth;
import org.jclouds.openstack.handlers.RetryOnRenew; import org.jclouds.openstack.keystone.v1_1.handlers.RetryOnRenew;
import org.jclouds.openstack.reference.AuthHeaders; import org.jclouds.openstack.services.Compute;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
import com.google.inject.Provides; import com.google.inject.Provides;
/** /**
@ -51,15 +57,15 @@ import com.google.inject.Provides;
@RequiresHttp @RequiresHttp
public class CloudServersRestClientModule extends RestClientModule<CloudServersClient, CloudServersAsyncClient> { public class CloudServersRestClientModule extends RestClientModule<CloudServersClient, CloudServersAsyncClient> {
private final OpenStackAuthenticationModule module; private final AuthenticationServiceModule module;
public CloudServersRestClientModule(OpenStackAuthenticationModule module) { public CloudServersRestClientModule(AuthenticationServiceModule module) {
super(CloudServersClient.class, CloudServersAsyncClient.class); super(CloudServersClient.class, CloudServersAsyncClient.class);
this.module = module; this.module = module;
} }
public CloudServersRestClientModule() { public CloudServersRestClientModule() {
this(new OpenStackAuthenticationModule()); this(new AuthenticationServiceModule());
} }
@Override @Override
@ -83,9 +89,20 @@ public class CloudServersRestClientModule extends RestClientModule<CloudServersC
@Provides @Provides
@Singleton @Singleton
@ServerManagement @Compute
protected URI provideServerUrl(AuthenticationResponse response) { protected URI provideServerUrl(Auth response) {
return response.getServices().get(AuthHeaders.SERVER_MANAGEMENT_URL); return Iterables.get(response.getServiceCatalog().get("cloudServers"), 0).getPublicURL();
} }
//TODO: see if we still need this.
@Provides
@Singleton
@TimeStamp
protected Supplier<Date> provideCacheBusterDate() {
return memoizeWithExpiration(new Supplier<Date>() {
public Date get() {
return new Date();
}
}, 1, TimeUnit.SECONDS);
}
} }

View File

@ -36,6 +36,7 @@ import java.net.UnknownHostException;
import java.util.Date; import java.util.Date;
import java.util.Properties; import java.util.Properties;
import javax.inject.Singleton;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.cloudservers.config.CloudServersRestClientModule; import org.jclouds.cloudservers.config.CloudServersRestClientModule;
@ -43,20 +44,23 @@ import org.jclouds.cloudservers.domain.BackupSchedule;
import org.jclouds.cloudservers.domain.DailyBackup; import org.jclouds.cloudservers.domain.DailyBackup;
import org.jclouds.cloudservers.domain.RebootType; import org.jclouds.cloudservers.domain.RebootType;
import org.jclouds.cloudservers.domain.WeeklyBackup; import org.jclouds.cloudservers.domain.WeeklyBackup;
import org.jclouds.cloudservers.internal.BaseCloudServersRestClientExpectTest.TestAuthenticationServiceModule;
import org.jclouds.cloudservers.options.CreateServerOptions; import org.jclouds.cloudservers.options.CreateServerOptions;
import org.jclouds.cloudservers.options.CreateSharedIpGroupOptions; import org.jclouds.cloudservers.options.CreateSharedIpGroupOptions;
import org.jclouds.cloudservers.options.ListOptions; import org.jclouds.cloudservers.options.ListOptions;
import org.jclouds.cloudservers.options.RebuildServerOptions; import org.jclouds.cloudservers.options.RebuildServerOptions;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.http.functions.ReturnFalseOn404; import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.http.functions.UnwrapOnlyJsonValue; import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
import org.jclouds.openstack.TestOpenStackAuthenticationModule;
import org.jclouds.openstack.filters.AddTimestampQuery; import org.jclouds.openstack.filters.AddTimestampQuery;
import org.jclouds.openstack.filters.AuthenticateRequest; import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.openstack.keystone.v1_1.config.AuthenticationServiceModule.GetAuth;
import org.jclouds.openstack.keystone.v1_1.domain.Auth;
import org.jclouds.openstack.keystone.v1_1.parse.ParseAuthTest;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest; import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
@ -71,6 +75,7 @@ import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.inject.Module; import com.google.inject.Module;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
/** /**
@ -78,8 +83,9 @@ import com.google.inject.TypeLiteral;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire // NOTE:without testName, this will not call @Before* and fail w/NPE during
@Test(groups = "unit", singleThreaded=true, testName = "CloudServersAsyncClientTest") // surefire
@Test(groups = "unit", singleThreaded = true, testName = "CloudServersAsyncClientTest")
public class CloudServersAsyncClientTest extends RestClientTest<CloudServersAsyncClient> { public class CloudServersAsyncClientTest extends RestClientTest<CloudServersAsyncClient> {
private static final Class<? extends ListOptions[]> listOptionsVarargsClass = new ListOptions[] {}.getClass(); private static final Class<? extends ListOptions[]> listOptionsVarargsClass = new ListOptions[] {}.getClass();
private static final Class<? extends CreateServerOptions[]> createServerOptionsVarargsClass = new CreateServerOptions[] {} private static final Class<? extends CreateServerOptions[]> createServerOptionsVarargsClass = new CreateServerOptions[] {}
@ -890,11 +896,22 @@ public class CloudServersAsyncClientTest extends RestClientTest<CloudServersAsyn
@RequiresHttp @RequiresHttp
protected static class TestCloudServersRestClientModule extends CloudServersRestClientModule { protected static class TestCloudServersRestClientModule extends CloudServersRestClientModule {
private TestCloudServersRestClientModule() { private TestCloudServersRestClientModule() {
super(new TestOpenStackAuthenticationModule()); super(new TestAuthenticationServiceModule());
}
@Provides
@Singleton
GetAuth provideGetAuth() {
return new GetAuth(null) {
@Override
public Auth apply(Credentials in) {
return new ParseAuthTest().expected();
}
};
} }
@Override @Override
protected URI provideServerUrl(AuthenticationResponse response) { protected URI provideServerUrl(Auth response) {
return URI.create("http://serverManagementUrl"); return URI.create("http://serverManagementUrl");
} }
@ -904,16 +921,15 @@ public class CloudServersAsyncClientTest extends RestClientTest<CloudServersAsyn
@Override @Override
public RestContextSpec<?, ?> createContextSpec() { public RestContextSpec<?, ?> createContextSpec() {
return new RestContextFactory(getProperties()).createContextSpec(provider, "user", "password", new Properties()); return new RestContextFactory(setupRestProperties()).createContextSpec(provider, "user", "password", setupProperties());
} }
@Override @Override
protected Properties getProperties() { protected Properties setupProperties() {
Properties overrides = new Properties(); Properties overrides = new Properties();
overrides.setProperty(PROPERTY_REGIONS, "US"); overrides.setProperty(PROPERTY_REGIONS, "US");
overrides.setProperty(PROPERTY_API_VERSION, "1"); overrides.setProperty(PROPERTY_API_VERSION, "1");
overrides.setProperty(provider + ".endpoint", "https://auth"); overrides.setProperty(provider + ".endpoint", "https://auth");
overrides.setProperty(provider + ".contextbuilder", CloudServersContextBuilder.class.getName());
return overrides; return overrides;
} }
} }

View File

@ -34,46 +34,21 @@ import com.google.common.collect.ImmutableMultimap;
@Test(groups = "unit", testName = "CloudServersExpectTest") @Test(groups = "unit", testName = "CloudServersExpectTest")
public class CloudServersExpectTest extends BaseCloudServersRestClientExpectTest { public class CloudServersExpectTest extends BaseCloudServersRestClientExpectTest {
HttpRequest initialAuth = HttpRequest.builder().method("GET").endpoint(URI.create("https://auth/v1.0"))
.headers(
ImmutableMultimap.<String, String> builder()
.put("X-Auth-User", "identity")
.put("X-Auth-Key", "credential")
.put("Accept", "*/*").build()).build();
String authToken = "d6245d35-22a0-47c0-9770-2c5097da25fc";
HttpResponse responseWithUrls = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content")
.headers(ImmutableMultimap.<String,String>builder()
.put("Server", "Apache/2.2.3 (Red Hat)")
.put("vary", "X-Auth-Token,X-Auth-Key,X-Storage-User,X-Storage-Pass")
.put("X-Storage-Url", "https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
.put("Cache-Control", "s-maxage=86399")
.put("Content-Type", "text/xml")
.put("Date", "Tue, 10 Jan 2012 22:08:47 GMT")
.put("X-Auth-Token", authToken)
.put("X-Server-Management-Url","https://servers.api.rackspacecloud.com/v1.0/413274")
.put("X-Storage-Token", authToken)
.put("Connection", "Keep-Alive")
.put("X-CDN-Management-Url", "https://cdn1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
.put("Content-Length", "0")
.build()).build();
public void deleteImageReturnsTrueOn200AndFalseOn404() { public void deleteImageReturnsTrueOn200AndFalseOn404() {
HttpRequest deleteImage11 = HttpRequest.builder().method("DELETE").endpoint( HttpRequest deleteImage11 = HttpRequest.builder().method("DELETE").endpoint(
URI.create("https://servers.api.rackspacecloud.com/v1.0/413274/images/11?now=1257695648897")).headers( URI.create("https://lon.servers.api.rackspacecloud.com/v1.0/10001786/images/11?now=1257695648897")).headers(
ImmutableMultimap.<String, String> builder() ImmutableMultimap.<String, String> builder()
.put("X-Auth-Token", authToken).build()).build(); .put("X-Auth-Token", authToken).build()).build();
HttpResponse imageDeleted = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content").build(); HttpResponse imageDeleted = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content").build();
CloudServersClient clientWhenImageExists = requestsSendResponses(initialAuth, responseWithUrls, deleteImage11, imageDeleted); CloudServersClient clientWhenImageExists = requestsSendResponses(initialAuth, responseWithAuth, deleteImage11, imageDeleted);
assert clientWhenImageExists.deleteImage(11); assert clientWhenImageExists.deleteImage(11);
HttpResponse imageNotFound = HttpResponse.builder().statusCode(404).message("HTTP/1.1 404 Not Found").build(); HttpResponse imageNotFound = HttpResponse.builder().statusCode(404).message("HTTP/1.1 404 Not Found").build();
CloudServersClient clientWhenImageDoesntExist = requestsSendResponses(initialAuth, responseWithUrls, deleteImage11, imageNotFound); CloudServersClient clientWhenImageDoesntExist = requestsSendResponses(initialAuth, responseWithAuth, deleteImage11, imageNotFound);
assert !clientWhenImageDoesntExist.deleteImage(11); assert !clientWhenImageDoesntExist.deleteImage(11);
} }

View File

@ -40,133 +40,75 @@ public class RetryOnRenewExpectTest extends BaseCloudServersRestClientExpectTest
@Test @Test
public void testShouldReauthenticateOn401() { public void testShouldReauthenticateOn401() {
String authToken = "d6245d35-22a0-47c0-9770-2c5097da25fc";
String authToken2 = "12345678-9012-47c0-9770-2c5097da25fc";
HttpRequest initialAuth = HttpRequest.builder().method("GET").endpoint(URI.create("https://auth/v1.0")) HttpRequest deleteImage = HttpRequest.builder().method("DELETE")
.headers( .endpoint(URI.create("https://lon.servers.api.rackspacecloud.com/v1.0/10001786/images/11?now=1257695648897"))
ImmutableMultimap.<String, String> builder() .headers(ImmutableMultimap.<String, String> builder().put("X-Auth-Token", authToken).build()).build();
.put("X-Auth-User", "identity")
.put("X-Auth-Key", "credential")
.put("Accept", "*/*").build()).build();
HttpResponse pleaseRenew = HttpResponse
HttpResponse responseWithUrls = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content") .builder()
.headers(ImmutableMultimap.<String,String>builder() .statusCode(401)
.put("Server", "Apache/2.2.3 (Red Hat)")
.put("vary", "X-Auth-Token,X-Auth-Key,X-Storage-User,X-Storage-Pass")
.put("X-Storage-Url", "https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
.put("Cache-Control", "s-maxage=86399")
.put("Content-Type", "text/xml")
.put("Date", "Tue, 10 Jan 2012 22:08:47 GMT")
.put("X-Auth-Token", authToken)
.put("X-Server-Management-Url","https://servers.api.rackspacecloud.com/v1.0/413274")
.put("X-Storage-Token", authToken)
.put("Connection", "Keep-Alive")
.put("X-CDN-Management-Url", "https://cdn1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
.put("Content-Length", "0")
.build()).build();
HttpRequest deleteImage = HttpRequest.builder().method("DELETE").endpoint(
URI.create("https://servers.api.rackspacecloud.com/v1.0/413274/images/11?now=1257695648897")).headers(
ImmutableMultimap.<String, String> builder()
.put("X-Auth-Token", authToken).build()).build();
HttpResponse pleaseRenew = HttpResponse.builder().statusCode(401)
.message("HTTP/1.1 401 Unauthorized") .message("HTTP/1.1 401 Unauthorized")
.payload(Payloads.newStringPayload("[{\"unauthorized\":{\"message\":\"Invalid authentication token. Please renew.\",\"code\":401}}]")) .payload(
Payloads
.newStringPayload("[{\"unauthorized\":{\"message\":\"Invalid authentication token. Please renew.\",\"code\":401}}]"))
.build(); .build();
// second auth uses same creds as initial one // second auth uses same creds as initial one
HttpRequest redoAuth = initialAuth; HttpRequest redoAuth = initialAuth;
HttpResponse responseWithUrls2 = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content") String authToken2 = "12345678-9012-47c0-9770-2c5097da25fc";
.headers(ImmutableMultimap.<String,String>builder()
.put("Server", "Apache/2.2.3 (Red Hat)")
.put("vary", "X-Auth-Token,X-Auth-Key,X-Storage-User,X-Storage-Pass")
.put("X-Storage-Url", "https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
.put("Cache-Control", "s-maxage=86399")
.put("Content-Type", "text/xml")
.put("Date", "Tue, 10 Jan 2012 22:08:47 GMT")
.put("X-Auth-Token", authToken2)
.put("X-Server-Management-Url","https://servers.api.rackspacecloud.com/v1.0/413274")
.put("X-Storage-Token", authToken2)
.put("Connection", "Keep-Alive")
.put("X-CDN-Management-Url", "https://cdn1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
.put("Content-Length", "0")
.build()).build();
HttpRequest deleteImage2 = HttpRequest.builder().method("DELETE").endpoint( HttpResponse responseWithUrls2 = HttpResponse
URI.create("https://servers.api.rackspacecloud.com/v1.0/413274/images/11?now=1257695648897")).headers( .Builder.from(responseWithAuth)
ImmutableMultimap.<String, String> builder() .payload(
.put("X-Auth-Token", authToken2).build()).build(); Payloads.newPayload(responseWithAuth.getPayload().getRawContent().toString()
.replace(authToken, authToken2))).build();
HttpRequest deleteImage2 = HttpRequest.builder().method("DELETE")
.endpoint(URI.create("https://lon.servers.api.rackspacecloud.com/v1.0/10001786/images/11?now=1257695648897"))
.headers(ImmutableMultimap.<String, String> builder().put("X-Auth-Token", authToken2).build()).build();
HttpResponse imageDeleted = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content").build(); HttpResponse imageDeleted = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content").build();
CloudServersClient clientWhenImageExists = orderedRequestsSendResponses(initialAuth, responseWithUrls, CloudServersClient clientWhenImageExists = orderedRequestsSendResponses(initialAuth, responseWithAuth,
deleteImage, pleaseRenew, redoAuth, responseWithUrls2, deleteImage2, imageDeleted); deleteImage, pleaseRenew, redoAuth, responseWithUrls2, deleteImage2, imageDeleted);
assert clientWhenImageExists.deleteImage(11); assert clientWhenImageExists.deleteImage(11);
} }
@Test(expectedExceptions=AuthorizationException.class) @Test(expectedExceptions = AuthorizationException.class)
public void testDoesNotReauthenticateOnFatal401() { public void testDoesNotReauthenticateOnFatal401() {
String authToken = "d6245d35-22a0-47c0-9770-2c5097da25fc"; HttpRequest deleteImage = HttpRequest.builder().method("DELETE")
.endpoint(URI.create("https://lon.servers.api.rackspacecloud.com/v1.0/10001786/images/11?now=1257695648897"))
.headers(ImmutableMultimap.<String, String> builder().put("X-Auth-Token", authToken).build()).build();
HttpRequest initialAuth = HttpRequest.builder().method("GET").endpoint(URI.create("https://auth/v1.0")) HttpResponse unauthResponse = HttpResponse
.headers( .builder()
ImmutableMultimap.<String, String> builder() .statusCode(401)
.put("X-Auth-User", "identity")
.put("X-Auth-Key", "credential")
.put("Accept", "*/*").build()).build();
HttpResponse responseWithUrls = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content")
.headers(ImmutableMultimap.<String,String>builder()
.put("Server", "Apache/2.2.3 (Red Hat)")
.put("vary", "X-Auth-Token,X-Auth-Key,X-Storage-User,X-Storage-Pass")
.put("X-Storage-Url", "https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
.put("Cache-Control", "s-maxage=86399")
.put("Content-Type", "text/xml")
.put("Date", "Tue, 10 Jan 2012 22:08:47 GMT")
.put("X-Auth-Token", authToken)
.put("X-Server-Management-Url","https://servers.api.rackspacecloud.com/v1.0/413274")
.put("X-Storage-Token", authToken)
.put("Connection", "Keep-Alive")
.put("X-CDN-Management-Url", "https://cdn1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
.put("Content-Length", "0")
.build()).build();
HttpRequest deleteImage = HttpRequest.builder().method("DELETE").endpoint(
URI.create("https://servers.api.rackspacecloud.com/v1.0/413274/images/11?now=1257695648897")).headers(
ImmutableMultimap.<String, String> builder()
.put("X-Auth-Token", authToken).build()).build();
HttpResponse unauthResponse = HttpResponse.builder().statusCode(401)
.message("HTTP/1.1 401 Unauthorized") .message("HTTP/1.1 401 Unauthorized")
.payload(Payloads.newStringPayload("[{\"unauthorized\":{\"message\":\"Fatal unauthorized.\",\"code\":401}}]")) .payload(
Payloads.newStringPayload("[{\"unauthorized\":{\"message\":\"Fatal unauthorized.\",\"code\":401}}]"))
.build(); .build();
CloudServersClient client = orderedRequestsSendResponses(initialAuth, responseWithUrls, CloudServersClient client = orderedRequestsSendResponses(initialAuth, responseWithAuth, deleteImage,
deleteImage, unauthResponse); unauthResponse);
client.deleteImage(11); client.deleteImage(11);
} }
// FIXME stack trace shows the AuthorizationException, but it's buried inside a guice TestException // FIXME stack trace shows the AuthorizationException, but it's buried inside
@Test(expectedExceptions=AuthorizationException.class) // a guice TestException
@Test(expectedExceptions = AuthorizationException.class)
public void testDoesNotReauthenticateOnAuthentication401() { public void testDoesNotReauthenticateOnAuthentication401() {
HttpRequest initialAuth = HttpRequest.builder().method("GET").endpoint(URI.create("https://auth/v1.0"))
.headers(
ImmutableMultimap.<String, String> builder()
.put("X-Auth-User", "identity")
.put("X-Auth-Key", "credential")
.put("Accept", "*/*").build()).build();
HttpResponse unauthResponse = HttpResponse
HttpResponse unauthResponse = HttpResponse.builder().statusCode(401) .builder()
.statusCode(401)
.message("HTTP/1.1 401 Unauthorized") .message("HTTP/1.1 401 Unauthorized")
.payload(Payloads.newStringPayload("[{\"unauthorized\":{\"message\":\"A different message implying fatal.\",\"code\":401}}]")) .payload(
Payloads
.newStringPayload("[{\"unauthorized\":{\"message\":\"A different message implying fatal.\",\"code\":401}}]"))
.build(); .build();
CloudServersClient client = requestSendsResponse(initialAuth, unauthResponse); CloudServersClient client = requestSendsResponse(initialAuth, unauthResponse);

View File

@ -29,9 +29,9 @@ import org.jclouds.cloudservers.CloudServersPropertiesBuilder;
import org.jclouds.cloudservers.config.CloudServersRestClientModule; import org.jclouds.cloudservers.config.CloudServersRestClientModule;
import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
import org.jclouds.openstack.filters.AddTimestampQuery; import org.jclouds.openstack.filters.AddTimestampQuery;
import org.jclouds.rest.BaseRestClientExpectTest; import org.jclouds.openstack.keystone.v1_1.config.AuthenticationServiceModule;
import org.jclouds.openstack.keystone.v1_1.internal.BaseKeystoneRestClientExpectTest;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
@ -42,7 +42,7 @@ import com.google.inject.Module;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class BaseCloudServersRestClientExpectTest extends BaseRestClientExpectTest<CloudServersClient> { public class BaseCloudServersRestClientExpectTest extends BaseKeystoneRestClientExpectTest<CloudServersClient> {
public BaseCloudServersRestClientExpectTest() { public BaseCloudServersRestClientExpectTest() {
provider = "cloudservers"; provider = "cloudservers";
@ -52,7 +52,7 @@ public class BaseCloudServersRestClientExpectTest extends BaseRestClientExpectTe
protected Properties setupRestProperties() { protected Properties setupRestProperties() {
Properties overrides = new Properties(); Properties overrides = new Properties();
overrides.setProperty(PROPERTY_REGIONS, "US"); overrides.setProperty(PROPERTY_REGIONS, "US");
overrides.setProperty(provider + ".endpoint", "https://auth"); overrides.setProperty(provider + ".endpoint", endpoint);
overrides.setProperty(provider + ".contextbuilder", CloudServersContextBuilder.class.getName()); overrides.setProperty(provider + ".contextbuilder", CloudServersContextBuilder.class.getName());
overrides.setProperty(provider + ".propertiesbuilder", CloudServersPropertiesBuilder.class.getName()); overrides.setProperty(provider + ".propertiesbuilder", CloudServersPropertiesBuilder.class.getName());
return overrides; return overrides;
@ -61,23 +61,14 @@ public class BaseCloudServersRestClientExpectTest extends BaseRestClientExpectTe
protected static final String CONSTANT_DATE = "2009-11-08T15:54:08.897Z"; protected static final String CONSTANT_DATE = "2009-11-08T15:54:08.897Z";
/** /**
* override so that we can control the timestamp used in {@link AddTimestampQuery} * override so that we can control the timestamp used in
* {@link AddTimestampQuery}
*/ */
static class TestOpenStackAuthenticationModule extends OpenStackAuthenticationModule { public static class TestAuthenticationServiceModule extends AuthenticationServiceModule {
@Override @Override
protected void configure() { protected void configure() {
super.configure(); super.configure();
} }
@Override
public Supplier<Date> provideCacheBusterDate() {
return new Supplier<Date>() {
public Date get() {
return new SimpleDateFormatDateService().iso8601DateParse(CONSTANT_DATE);
}
};
}
} }
@Override @Override
@ -89,8 +80,16 @@ public class BaseCloudServersRestClientExpectTest extends BaseRestClientExpectTe
@RequiresHttp @RequiresHttp
protected static class TestCloudServersRestClientModule extends CloudServersRestClientModule { protected static class TestCloudServersRestClientModule extends CloudServersRestClientModule {
private TestCloudServersRestClientModule() { private TestCloudServersRestClientModule() {
super(new TestOpenStackAuthenticationModule()); super(new TestAuthenticationServiceModule());
} }
@Override
public Supplier<Date> provideCacheBusterDate() {
return new Supplier<Date>() {
public Date get() {
return new SimpleDateFormatDateService().iso8601DateParse(CONSTANT_DATE);
}
};
}
} }
} }

View File

@ -18,7 +18,6 @@
*/ */
package org.jclouds.cloudsigma; package org.jclouds.cloudsigma;
import static com.google.common.base.Preconditions.checkArgument;
import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.cloudsigma.reference.CloudSigmaConstants.PROPERTY_VNC_PASSWORD; import static org.jclouds.cloudsigma.reference.CloudSigmaConstants.PROPERTY_VNC_PASSWORD;
@ -48,11 +47,4 @@ public class CloudSigmaPropertiesBuilder extends PropertiesBuilder {
super(properties); super(properties);
} }
@Override
public Properties build() {
Properties props = super.build();
checkArgument(props.getProperty(PROPERTY_VNC_PASSWORD).length() <= 8,
"vnc passwords should be less that 8 characters!");
return props;
}
} }

View File

@ -18,6 +18,7 @@
*/ */
package org.jclouds.cloudsigma.compute; package org.jclouds.cloudsigma.compute;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.filter;
import static org.jclouds.concurrent.FutureIterables.transformParallel; import static org.jclouds.concurrent.FutureIterables.transformParallel;
@ -104,6 +105,7 @@ public class CloudSigmaComputeServiceAdapter implements
this.driveNotClaimed = checkNotNull(driveNotClaimed, "driveNotClaimed"); this.driveNotClaimed = checkNotNull(driveNotClaimed, "driveNotClaimed");
this.locationSupplier = checkNotNull(locationSupplier, "locationSupplier"); this.locationSupplier = checkNotNull(locationSupplier, "locationSupplier");
this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword"); this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword");
checkArgument(defaultVncPassword.length() <= 8, "vnc passwords should be less that 8 characters!");
this.cache = checkNotNull(cache, "cache"); this.cache = checkNotNull(cache, "cache");
this.executor = checkNotNull(executor, "executor"); this.executor = checkNotNull(executor, "executor");
} }
@ -159,7 +161,7 @@ public class CloudSigmaComputeServiceAdapter implements
return "sizeLessThanOrEqual(" + size + ")"; return "sizeLessThanOrEqual(" + size + ")";
} }
}).ids(id).ram(ram).processors(ImmutableList.of(new Processor(1, cpu))) }).ids(id).ram(ram).processors(ImmutableList.of(new Processor(1, cpu))).hypervisor("kvm")
.volumes(ImmutableList.<Volume>of(new VolumeImpl(size, true, true))).build()); .volumes(ImmutableList.<Volume>of(new VolumeImpl(size, true, true))).build());
} }
return hardware.build(); return hardware.build();

View File

@ -99,7 +99,7 @@ public class ServerInfoToNodeMetadata implements Function<ServerInfo, NodeMetada
builder.operatingSystem(image.getOperatingSystem()); builder.operatingSystem(image.getOperatingSystem());
} }
} }
builder.hardware(new HardwareBuilder().ids(from.getUuid()) builder.hardware(new HardwareBuilder().ids(from.getUuid()).hypervisor("kvm")
.processors(ImmutableList.of(new Processor(1, from.getCpu()))).ram(from.getMem()) .processors(ImmutableList.of(new Processor(1, from.getCpu()))).ram(from.getMem())
.volumes(Iterables.transform(from.getDevices().values(), deviceToVolume)).build()); .volumes(Iterables.transform(from.getDevices().values(), deviceToVolume)).build());
builder.state(serverStatusToNodeState.get(from.getStatus())); builder.state(serverStatusToNodeState.get(from.getStatus()));

View File

@ -34,6 +34,7 @@ import org.jclouds.cloudstack.features.NetworkAsyncClient;
import org.jclouds.cloudstack.features.OfferingAsyncClient; import org.jclouds.cloudstack.features.OfferingAsyncClient;
import org.jclouds.cloudstack.features.SSHKeyPairAsyncClient; import org.jclouds.cloudstack.features.SSHKeyPairAsyncClient;
import org.jclouds.cloudstack.features.SecurityGroupAsyncClient; import org.jclouds.cloudstack.features.SecurityGroupAsyncClient;
import org.jclouds.cloudstack.features.SessionAsyncClient;
import org.jclouds.cloudstack.features.SnapshotAsyncClient; import org.jclouds.cloudstack.features.SnapshotAsyncClient;
import org.jclouds.cloudstack.features.TemplateAsyncClient; import org.jclouds.cloudstack.features.TemplateAsyncClient;
import org.jclouds.cloudstack.features.VMGroupAsyncClient; import org.jclouds.cloudstack.features.VMGroupAsyncClient;
@ -184,4 +185,10 @@ public interface CloudStackAsyncClient {
*/ */
@Delegate @Delegate
SnapshotAsyncClient getSnapshotClient(); SnapshotAsyncClient getSnapshotClient();
/**
* Provides asynchronous access to Sessions
*/
@Delegate
SessionAsyncClient getSessionClient();
} }

View File

@ -18,8 +18,6 @@
*/ */
package org.jclouds.cloudstack; package org.jclouds.cloudstack;
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.features.AccountClient; import org.jclouds.cloudstack.features.AccountClient;
import org.jclouds.cloudstack.features.AddressClient; import org.jclouds.cloudstack.features.AddressClient;
import org.jclouds.cloudstack.features.AsyncJobClient; import org.jclouds.cloudstack.features.AsyncJobClient;
@ -41,10 +39,13 @@ import org.jclouds.cloudstack.features.TemplateClient;
import org.jclouds.cloudstack.features.VMGroupClient; import org.jclouds.cloudstack.features.VMGroupClient;
import org.jclouds.cloudstack.features.VirtualMachineClient; import org.jclouds.cloudstack.features.VirtualMachineClient;
import org.jclouds.cloudstack.features.VolumeClient; import org.jclouds.cloudstack.features.VolumeClient;
import org.jclouds.cloudstack.features.SessionClient;
import org.jclouds.cloudstack.features.ZoneClient; import org.jclouds.cloudstack.features.ZoneClient;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import java.util.concurrent.TimeUnit;
/** /**
* Provides synchronous access to CloudStack. * Provides synchronous access to CloudStack.
* <p/> * <p/>
@ -187,4 +188,10 @@ public interface CloudStackClient {
*/ */
@Delegate @Delegate
SnapshotClient getSnapshotClient(); SnapshotClient getSnapshotClient();
/**
* Provides synchronous access to Sessions
*/
@Delegate
SessionClient getSessionClient();
} }

View File

@ -30,6 +30,7 @@ import org.jclouds.cloudstack.features.GlobalPodAsyncClient;
import org.jclouds.cloudstack.features.GlobalStoragePoolAsyncClient; import org.jclouds.cloudstack.features.GlobalStoragePoolAsyncClient;
import org.jclouds.cloudstack.features.GlobalUsageAsyncClient; import org.jclouds.cloudstack.features.GlobalUsageAsyncClient;
import org.jclouds.cloudstack.features.GlobalUserAsyncClient; import org.jclouds.cloudstack.features.GlobalUserAsyncClient;
import org.jclouds.cloudstack.features.GlobalVlanAsyncClient;
import org.jclouds.cloudstack.features.GlobalZoneAsyncClient; import org.jclouds.cloudstack.features.GlobalZoneAsyncClient;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
@ -122,4 +123,10 @@ public interface CloudStackGlobalAsyncClient extends CloudStackDomainAsyncClient
*/ */
@Delegate @Delegate
GlobalPodAsyncClient getPodClient(); GlobalPodAsyncClient getPodClient();
/**
* Provides asynchronous access to Vlan
*/
@Delegate
GlobalVlanAsyncClient getVlanClient();
} }

View File

@ -31,6 +31,7 @@ import org.jclouds.cloudstack.features.GlobalPodClient;
import org.jclouds.cloudstack.features.GlobalStoragePoolClient; import org.jclouds.cloudstack.features.GlobalStoragePoolClient;
import org.jclouds.cloudstack.features.GlobalUsageClient; import org.jclouds.cloudstack.features.GlobalUsageClient;
import org.jclouds.cloudstack.features.GlobalUserClient; import org.jclouds.cloudstack.features.GlobalUserClient;
import org.jclouds.cloudstack.features.GlobalVlanClient;
import org.jclouds.cloudstack.features.GlobalZoneClient; import org.jclouds.cloudstack.features.GlobalZoneClient;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
@ -125,4 +126,10 @@ public interface CloudStackGlobalClient extends CloudStackDomainClient {
*/ */
@Delegate @Delegate
GlobalPodClient getPodClient(); GlobalPodClient getPodClient();
/**
* Provides synchronous access to Vlan
*/
@Delegate
GlobalVlanClient getVlanClient();
} }

View File

@ -18,12 +18,12 @@
*/ */
package org.jclouds.cloudstack; package org.jclouds.cloudstack;
import static org.jclouds.Constants.PROPERTY_API_VERSION; import org.jclouds.PropertiesBuilder;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import java.util.Properties; import java.util.Properties;
import org.jclouds.PropertiesBuilder; import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
/** /**
* Builds properties used in cloudstack Clients * Builds properties used in cloudstack Clients

View File

@ -41,6 +41,7 @@ public class ServiceOfferingToHardware implements Function<ServiceOffering, Hard
.tags(offering.getTags()) .tags(offering.getTags())
.processors(ImmutableList.of(new Processor(offering.getCpuNumber(), offering.getCpuSpeed()))) .processors(ImmutableList.of(new Processor(offering.getCpuNumber(), offering.getCpuSpeed())))
.ram(offering.getMemory())// .ram(offering.getMemory())//
// TODO: hypervisor probably from zone?
// TODO .volumes() // TODO .volumes()
// displayText // displayText
// created // created

View File

@ -18,43 +18,49 @@
*/ */
package org.jclouds.cloudstack.compute.functions; package org.jclouds.cloudstack.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.transform;
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.collect.FindResourceInSet;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Location;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.util.InetAddresses2;
import org.jclouds.util.Throwables2;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.UncheckedExecutionException; import com.google.common.util.concurrent.UncheckedExecutionException;
import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.NIC;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.collect.FindResourceInSet;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Processor;
import org.jclouds.domain.Location;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.util.InetAddresses2;
import org.jclouds.util.Throwables2;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Sets.newHashSet;
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
import static org.jclouds.util.InetAddresses2.isPrivateIPAddress;
/** /**
* @author Adrian Cole * @author Adrian Cole, Andrei Savu
*/ */
@Singleton @Singleton
public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, NodeMetadata> { public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, NodeMetadata> {
@ -72,17 +78,14 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
.put(VirtualMachine.State.UNRECOGNIZED, NodeState.UNRECOGNIZED).build(); .put(VirtualMachine.State.UNRECOGNIZED, NodeState.UNRECOGNIZED).build();
private final FindLocationForVirtualMachine findLocationForVirtualMachine; private final FindLocationForVirtualMachine findLocationForVirtualMachine;
private final FindHardwareForVirtualMachine findHardwareForVirtualMachine;
private final FindImageForVirtualMachine findImageForVirtualMachine; private final FindImageForVirtualMachine findImageForVirtualMachine;
private final LoadingCache<Long, Set<IPForwardingRule>> getIPForwardingRulesByVirtualMachine; private final LoadingCache<Long, Set<IPForwardingRule>> getIPForwardingRulesByVirtualMachine;
@Inject @Inject
VirtualMachineToNodeMetadata(FindLocationForVirtualMachine findLocationForVirtualMachine, VirtualMachineToNodeMetadata(FindLocationForVirtualMachine findLocationForVirtualMachine,
FindHardwareForVirtualMachine findHardwareForVirtualMachine,
FindImageForVirtualMachine findImageForVirtualMachine, FindImageForVirtualMachine findImageForVirtualMachine,
LoadingCache<Long, Set<IPForwardingRule>> getIPForwardingRulesByVirtualMachine) { LoadingCache<Long, Set<IPForwardingRule>> getIPForwardingRulesByVirtualMachine) {
this.findLocationForVirtualMachine = checkNotNull(findLocationForVirtualMachine, "findLocationForVirtualMachine"); this.findLocationForVirtualMachine = checkNotNull(findLocationForVirtualMachine, "findLocationForVirtualMachine");
this.findHardwareForVirtualMachine = checkNotNull(findHardwareForVirtualMachine, "findHardwareForVirtualMachine");
this.findImageForVirtualMachine = checkNotNull(findImageForVirtualMachine, "findImageForVirtualMachine"); this.findImageForVirtualMachine = checkNotNull(findImageForVirtualMachine, "findImageForVirtualMachine");
this.getIPForwardingRulesByVirtualMachine = checkNotNull(getIPForwardingRulesByVirtualMachine, this.getIPForwardingRulesByVirtualMachine = checkNotNull(getIPForwardingRulesByVirtualMachine,
"getIPForwardingRulesByVirtualMachine"); "getIPForwardingRulesByVirtualMachine");
@ -109,24 +112,39 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
builder.operatingSystem(image.getOperatingSystem()); builder.operatingSystem(image.getOperatingSystem());
} }
Hardware hardware = findHardwareForVirtualMachine.apply(from); builder.hardware(new HardwareBuilder()
if (hardware != null) .ids(from.getServiceOfferingId() + "")
builder.hardware(hardware); .name(from.getServiceOfferingName() + "")
// .tags() TODO
.processors(ImmutableList.of(new Processor(from.getCpuCount(), from.getCpuSpeed())))
.ram((int)from.getMemory())//
.hypervisor(from.getHypervisor())//
.build());
builder.state(vmStateToNodeState.get(from.getState())); builder.state(vmStateToNodeState.get(from.getState()));
// TODO: check to see public or private Set<String> publicAddresses = newHashSet(), privateAddresses = newHashSet();
if (from.getIPAddress() != null) { if (from.getIPAddress() != null) {
boolean isPrivate = InetAddresses2.isPrivateIPAddress(from.getIPAddress()); boolean isPrivate = isPrivateIPAddress(from.getIPAddress());
Set<String> addresses = ImmutableSet.<String> of(from.getIPAddress()); if (isPrivate) {
if (isPrivate) privateAddresses.add(from.getIPAddress());
builder.privateAddresses(addresses); } else {
else publicAddresses.add(from.getIPAddress());
builder.publicAddresses(addresses); }
}
for (NIC nic : from.getNICs()) {
if (nic.getIPAddress() != null) {
if (isPrivateIPAddress(nic.getIPAddress())) {
privateAddresses.add(nic.getIPAddress());
} else {
publicAddresses.add(nic.getIPAddress());
}
}
} }
try { try {
/* Also add to the list of public IPs any public IP address that has a
builder.publicAddresses(transform( forwarding rule that links to this machine */
Iterables.addAll(publicAddresses, transform(
filter(getIPForwardingRulesByVirtualMachine.getUnchecked(from.getId()), filter(getIPForwardingRulesByVirtualMachine.getUnchecked(from.getId()),
new Predicate<IPForwardingRule>() { new Predicate<IPForwardingRule>() {
@Override @Override
@ -145,7 +163,7 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
throw e; throw e;
} }
} }
return builder.build(); return builder.privateAddresses(privateAddresses).publicAddresses(publicAddresses).build();
} }
@Singleton @Singleton

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,17 @@
*/ */
package org.jclouds.cloudstack.config; package org.jclouds.cloudstack.config;
import com.google.common.collect.ImmutableMap; import static com.google.common.base.Throwables.propagate;
import com.google.inject.Provides; import static org.jclouds.rest.config.BinderUtils.bindClientAndAsyncClient;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral; import java.net.URI;
import com.google.inject.name.Named; 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.CloudStackAsyncClient;
import org.jclouds.cloudstack.CloudStackClient; import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.CloudStackDomainAsyncClient; import org.jclouds.cloudstack.CloudStackDomainAsyncClient;
@ -30,6 +36,7 @@ import org.jclouds.cloudstack.CloudStackDomainClient;
import org.jclouds.cloudstack.CloudStackGlobalAsyncClient; import org.jclouds.cloudstack.CloudStackGlobalAsyncClient;
import org.jclouds.cloudstack.CloudStackGlobalClient; import org.jclouds.cloudstack.CloudStackGlobalClient;
import org.jclouds.cloudstack.collections.Integration; import org.jclouds.cloudstack.collections.Integration;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.cloudstack.features.AccountAsyncClient; import org.jclouds.cloudstack.features.AccountAsyncClient;
import org.jclouds.cloudstack.features.AccountClient; import org.jclouds.cloudstack.features.AccountClient;
import org.jclouds.cloudstack.features.AddressAsyncClient; import org.jclouds.cloudstack.features.AddressAsyncClient;
@ -72,6 +79,8 @@ import org.jclouds.cloudstack.features.GlobalUsageAsyncClient;
import org.jclouds.cloudstack.features.GlobalUsageClient; import org.jclouds.cloudstack.features.GlobalUsageClient;
import org.jclouds.cloudstack.features.GlobalUserAsyncClient; import org.jclouds.cloudstack.features.GlobalUserAsyncClient;
import org.jclouds.cloudstack.features.GlobalUserClient; import org.jclouds.cloudstack.features.GlobalUserClient;
import org.jclouds.cloudstack.features.GlobalVlanAsyncClient;
import org.jclouds.cloudstack.features.GlobalVlanClient;
import org.jclouds.cloudstack.features.GlobalZoneAsyncClient; import org.jclouds.cloudstack.features.GlobalZoneAsyncClient;
import org.jclouds.cloudstack.features.GlobalZoneClient; import org.jclouds.cloudstack.features.GlobalZoneClient;
import org.jclouds.cloudstack.features.GuestOSAsyncClient; import org.jclouds.cloudstack.features.GuestOSAsyncClient;
@ -94,6 +103,8 @@ import org.jclouds.cloudstack.features.SSHKeyPairAsyncClient;
import org.jclouds.cloudstack.features.SSHKeyPairClient; import org.jclouds.cloudstack.features.SSHKeyPairClient;
import org.jclouds.cloudstack.features.SecurityGroupAsyncClient; import org.jclouds.cloudstack.features.SecurityGroupAsyncClient;
import org.jclouds.cloudstack.features.SecurityGroupClient; import org.jclouds.cloudstack.features.SecurityGroupClient;
import org.jclouds.cloudstack.features.SessionAsyncClient;
import org.jclouds.cloudstack.features.SessionClient;
import org.jclouds.cloudstack.features.SnapshotAsyncClient; import org.jclouds.cloudstack.features.SnapshotAsyncClient;
import org.jclouds.cloudstack.features.SnapshotClient; import org.jclouds.cloudstack.features.SnapshotClient;
import org.jclouds.cloudstack.features.TemplateAsyncClient; import org.jclouds.cloudstack.features.TemplateAsyncClient;
@ -106,8 +117,16 @@ import org.jclouds.cloudstack.features.VolumeAsyncClient;
import org.jclouds.cloudstack.features.VolumeClient; import org.jclouds.cloudstack.features.VolumeClient;
import org.jclouds.cloudstack.features.ZoneAsyncClient; import org.jclouds.cloudstack.features.ZoneAsyncClient;
import org.jclouds.cloudstack.features.ZoneClient; 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.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.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError; import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection; import org.jclouds.http.annotation.Redirection;
@ -120,9 +139,17 @@ import org.jclouds.rest.config.BinderUtils;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
import org.jclouds.rest.internal.RestContextImpl; import org.jclouds.rest.internal.RestContextImpl;
import javax.ws.rs.core.UriBuilder; import com.google.common.base.Function;
import java.net.URI; import com.google.common.base.Supplier;
import java.util.Map; 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. * Configures the cloudstack connection.
@ -172,6 +199,8 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
.put(GlobalStoragePoolClient.class, GlobalStoragePoolAsyncClient.class)// .put(GlobalStoragePoolClient.class, GlobalStoragePoolAsyncClient.class)//
.put(GlobalUsageClient.class, GlobalUsageAsyncClient.class)// .put(GlobalUsageClient.class, GlobalUsageAsyncClient.class)//
.put(GlobalPodClient.class, GlobalPodAsyncClient.class)// .put(GlobalPodClient.class, GlobalPodAsyncClient.class)//
.put(GlobalVlanClient.class, GlobalVlanAsyncClient.class)//
.put(SessionClient.class, SessionAsyncClient.class)//
.build(); .build();
@Override @Override
@ -208,6 +237,12 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
}).to(new TypeLiteral<RestContextImpl<CloudStackGlobalClient, CloudStackGlobalAsyncClient>>() { }).to(new TypeLiteral<RestContextImpl<CloudStackGlobalClient, CloudStackGlobalAsyncClient>>() {
}); });
install(new CloudStackParserModule()); install(new CloudStackParserModule());
bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class);
// session client is used directly for filters and retry handlers, so let's bind it explicitly
bindClientAndAsyncClient(binder(), SessionClient.class, SessionAsyncClient.class);
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenewAndLogoutOnClose.class);
super.configure(); super.configure();
} }
@ -224,7 +259,80 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
protected URI providesIntegrationEndpoint(@Provider URI normal, protected URI providesIntegrationEndpoint(@Provider URI normal,
@Named("jclouds.cloudstack.integration-api-port") int port, @Named("jclouds.cloudstack.integration-api-port") int port,
com.google.inject.Provider<UriBuilder> uriBuilder) { com.google.inject.Provider<UriBuilder> uriBuilder) {
return uriBuilder.get().scheme(normal.getScheme()) return uriBuilder.get().scheme(normal.getScheme()).host(normal.getHost()).path("/").port(port).build();
.host(normal.getHost()).path("/").port(port).build(); }
@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

@ -16,36 +16,31 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.glesys.domain; package org.jclouds.cloudstack.config;
import com.google.common.base.CaseFormat;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.CaseFormat;
/** /**
* Valid states for a server hosted in a Glesys cloud * Decides what type of credentials createContext is supplied with.
* *
* @author Adam Lowe * @author Adrian Cole
* @see ServerStatus
*/ */
public enum ServerState { public enum CredentialType {
RUNNING, STOPPED, UNRECOGNIZED; API_ACCESS_KEY_CREDENTIALS,
public String value() { PASSWORD_CREDENTIALS;
return (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()));
}
@Override @Override
public String toString() { public String toString() {
return value(); return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name());
} }
public static ServerState fromValue(String state) { public static CredentialType fromValue(String credentialType) {
try { return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(credentialType,
return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(state, "state"))); "credentialType")));
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
} }
} }

View File

@ -0,0 +1,350 @@
/**
* 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.domain;
import com.google.gson.annotations.SerializedName;
/**
* Representation of the login API call response
*
* @author Andrei Savu
*/
public class LoginResponse implements Comparable<LoginResponse> {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String username;
private long userId;
private String password;
private long domainId;
private long timeout;
private boolean registered;
private String accountName;
private String firstName;
private String lastName;
private Account.Type accountType;
private String timezone;
private String timezoneOffset;
private String sessionKey;
private String jSessionId;
public Builder copyOf(LoginResponse r) {
this.username = r.username;
this.userId = r.userId;
this.password = r.password;
this.domainId = r.domainId;
this.timeout = r.timeout;
this.registered = r.registered;
this.accountName = r.accountName;
this.firstName = r.firstName;
this.lastName = r.lastName;
this.accountType = r.accountType;
this.timezone = r.timezone;
this.timezoneOffset = r.timezoneOffset;
this.sessionKey = r.sessionKey;
this.jSessionId = r.jSessionId;
return this;
}
public Builder username(String username) {
this.username = username;
return this;
}
public Builder userId(long userId) {
this.userId = userId;
return this;
}
public Builder password(String password) {
this.password = password;
return this;
}
public Builder domainId(long domainId) {
this.domainId = domainId;
return this;
}
public Builder timeout(long timeout) {
this.timeout = timeout;
return this;
}
public Builder registered(boolean registered) {
this.registered = registered;
return this;
}
public Builder accountName(String accountName) {
this.accountName = accountName;
return this;
}
public Builder firstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder lastName(String lastName) {
this.lastName = lastName;
return this;
}
public Builder accountType(Account.Type accountType) {
this.accountType = accountType;
return this;
}
public Builder timezone(String timezone) {
this.timezone = timezone;
return this;
}
public Builder timezoneOffset(String timezoneOffset) {
this.timezoneOffset = timezoneOffset;
return this;
}
public Builder sessionKey(String sessionKey) {
this.sessionKey = sessionKey;
return this;
}
public Builder jSessionId(String jSessionId) {
this.jSessionId = jSessionId;
return this;
}
public LoginResponse build() {
return new LoginResponse(username, userId, password, domainId, timeout, registered, accountName, firstName,
lastName, accountType, timezone, timezoneOffset, sessionKey, jSessionId);
}
}
private final String username;
@SerializedName("userid")
private final long userId;
private final String password;
@SerializedName("domainid")
private final long domainId;
private final long timeout;
private final boolean registered;
@SerializedName("account")
private final String accountName;
@SerializedName("firstname")
private final String firstName;
@SerializedName("lastname")
private final String lastName;
@SerializedName("type")
private final Account.Type accountType;
private final String timezone;
@SerializedName("timezoneoffset")
private final String timezoneOffset;
@SerializedName("sessionkey")
private final String sessionKey;
private final String jSessionId;
public LoginResponse(String username, long userId, String password, long domainId, long timeout, boolean registered,
String accountName, String firstName, String lastName, Account.Type accountType, String timezone,
String timezoneOffset, String sessionKey, String jSessionId) {
this.username = username;
this.userId = userId;
this.password = password;
this.domainId = domainId;
this.timeout = timeout;
this.registered = registered;
this.accountName = accountName;
this.firstName = firstName;
this.lastName = lastName;
this.accountType = accountType;
this.timezone = timezone;
this.timezoneOffset = timezoneOffset;
this.sessionKey = sessionKey;
this.jSessionId = jSessionId;
}
public String getUsername() {
return username;
}
public long getUserId() {
return userId;
}
public String getPassword() {
return password;
}
public long getDomainId() {
return domainId;
}
public long getTimeout() {
return timeout;
}
public boolean isRegistered() {
return registered;
}
public String getAccountName() {
return accountName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public Account.Type getAccountType() {
return accountType;
}
public String getTimezone() {
return timezone;
}
public String getTimezoneOffset() {
return timezoneOffset;
}
public String getSessionKey() {
return sessionKey;
}
public String getJSessionId() {
return jSessionId;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LoginResponse other = (LoginResponse) obj;
if (accountName == null) {
if (other.accountName != null)
return false;
} else if (!accountName.equals(other.accountName))
return false;
if (accountType == null) {
if (other.accountType != null)
return false;
} else if (!accountType.equals(other.accountType))
return false;
if (domainId != other.domainId)
return false;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (jSessionId == null) {
if (other.jSessionId != null)
return false;
} else if (!jSessionId.equals(other.jSessionId))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
if (password == null) {
if (other.password != null)
return false;
} else if (!password.equals(other.password))
return false;
if (registered != other.registered)
return false;
if (sessionKey == null) {
if (other.sessionKey != null)
return false;
} else if (!sessionKey.equals(other.sessionKey))
return false;
if (timeout != other.timeout)
return false;
if (timezone == null) {
if (other.timezone != null)
return false;
} else if (!timezone.equals(other.timezone))
return false;
if (timezoneOffset == null) {
if (other.timezoneOffset != null)
return false;
} else if (!timezoneOffset.equals(other.timezoneOffset))
return false;
if (userId != other.userId)
return false;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((accountName == null) ? 0 : accountName.hashCode());
result = prime * result + ((accountType == null) ? 0 : accountType.hashCode());
result = prime * result + (int) (domainId ^ (domainId >>> 32));
result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result + ((jSessionId == null) ? 0 : jSessionId.hashCode());
result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
result = prime * result + ((password == null) ? 0 : password.hashCode());
result = prime * result + (registered ? 1231 : 1237);
result = prime * result + ((sessionKey == null) ? 0 : sessionKey.hashCode());
result = prime * result + (int) (timeout ^ (timeout >>> 32));
result = prime * result + ((timezone == null) ? 0 : timezone.hashCode());
result = prime * result + ((timezoneOffset == null) ? 0 : timezoneOffset.hashCode());
result = prime * result + (int) (userId ^ (userId >>> 32));
result = prime * result + ((username == null) ? 0 : username.hashCode());
return result;
}
@Override
public String toString() {
return "LoginResponse{" + "username='" + username + '\'' + ", userId=" + userId + ", password='" + password
+ '\'' + ", domainId=" + domainId + ", timeout=" + timeout + ", registered=" + registered
+ ", accountName='" + accountName + '\'' + ", firstName='" + firstName + '\'' + ", lastName='"
+ lastName + '\'' + ", accountType=" + accountType + ", timezone='" + timezone + '\''
+ ", timezoneOffset='" + timezoneOffset + '\'' + ", sessionKey='" + sessionKey + '\'' + ", jSessionId='"
+ jSessionId + '\'' + '}';
}
@Override
public int compareTo(LoginResponse arg0) {
return sessionKey.compareTo(arg0.getSessionKey());
}
}

View File

@ -0,0 +1,305 @@
/**
* 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.domain;
import com.google.gson.annotations.SerializedName;
/**
* Represents the data object used in CloudStack's "Vlan" API.
*
* @author Richard Downer
*/
public class VlanIPRange implements Comparable<VlanIPRange> {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private long id;
private String description;
private boolean forVirtualNetwork;
private long zoneId;
private String vlan;
private String account;
private long domainId;
private String domain;
private long podId;
private String podName;
private String gateway;
private String netmask;
private String startIP;
private String endIP;
private long networkId;
public Builder id(long id) {
this.id = id;
return this;
}
public Builder description(String description) {
this.description = description;
return this;
}
public Builder forVirtualNetwork(boolean forVirtualNetwork) {
this.forVirtualNetwork = forVirtualNetwork;
return this;
}
public Builder zoneId(long zoneId) {
this.zoneId = zoneId;
return this;
}
public Builder vlan(long vlan) {
this.vlan = vlan+"";
return this;
}
public Builder vlan(String vlan) {
this.vlan = vlan;
return this;
}
public Builder account(String account) {
this.account = account;
return this;
}
public Builder domainId(long domainId) {
this.domainId = domainId;
return this;
}
public Builder domain(String domain) {
this.domain = domain;
return this;
}
public Builder podId(long podId) {
this.podId = podId;
return this;
}
public Builder podName(String podName) {
this.podName = podName;
return this;
}
public Builder gateway(String gateway) {
this.gateway = gateway;
return this;
}
public Builder netmask(String netmask) {
this.netmask = netmask;
return this;
}
public Builder startIP(String startIP) {
this.startIP = startIP;
return this;
}
public Builder endIP(String endIP) {
this.endIP = endIP;
return this;
}
public Builder networkId(long networkId) {
this.networkId = networkId;
return this;
}
public VlanIPRange build() {
return new VlanIPRange(id, description, forVirtualNetwork, zoneId, vlan, account, domainId, domain, podId, podName, gateway, netmask, startIP, endIP, networkId);
}
}
private long id;
private String description;
@SerializedName("forvirtualnetwork") private boolean forVirtualNetwork;
@SerializedName("zoneid") private long zoneId;
private String vlan;
private String account;
@SerializedName("domainid") private long domainId;
private String domain;
@SerializedName("podid") private long podId;
@SerializedName("podname") private String podName;
private String gateway;
private String netmask;
@SerializedName("startip") private String startIP;
@SerializedName("endip") private String endIP;
@SerializedName("networkid") private long networkId;
/* just for the deserializer */
VlanIPRange() {}
public VlanIPRange(long id, String description, boolean forVirtualNetwork, long zoneId, String vlan, String account, long domainId, String domain, long podId, String podName, String gateway, String netmask, String startIP, String endIP, long networkId) {
this.id = id;
this.description = description;
this.forVirtualNetwork = forVirtualNetwork;
this.zoneId = zoneId;
this.vlan = vlan;
this.account = account;
this.domainId = domainId;
this.domain = domain;
this.podId = podId;
this.podName = podName;
this.gateway = gateway;
this.netmask = netmask;
this.startIP = startIP;
this.endIP = endIP;
this.networkId = networkId;
}
public long getId() {
return id;
}
public String getDescription() {
return description;
}
public boolean isForVirtualNetwork() {
return forVirtualNetwork;
}
public long getZoneId() {
return zoneId;
}
public String getVlan() {
return vlan;
}
public String getAccount() {
return account;
}
public long getDomainId() {
return domainId;
}
public String getDomain() {
return domain;
}
public long getPodId() {
return podId;
}
public String getPodName() {
return podName;
}
public String getGateway() {
return gateway;
}
public String getNetmask() {
return netmask;
}
public String getStartIP() {
return startIP;
}
public String getEndIP() {
return endIP;
}
public long getNetworkId() {
return networkId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
VlanIPRange that = (VlanIPRange) o;
if (domainId != that.domainId) return false;
if (forVirtualNetwork != that.forVirtualNetwork) return false;
if (id != that.id) return false;
if (networkId != that.networkId) return false;
if (podId != that.podId) return false;
if (zoneId != that.zoneId) return false;
if (account != null ? !account.equals(that.account) : that.account != null) return false;
if (description != null ? !description.equals(that.description) : that.description != null) return false;
if (domain != null ? !domain.equals(that.domain) : that.domain != null) return false;
if (endIP != null ? !endIP.equals(that.endIP) : that.endIP != null) return false;
if (gateway != null ? !gateway.equals(that.gateway) : that.gateway != null) return false;
if (netmask != null ? !netmask.equals(that.netmask) : that.netmask != null) return false;
if (podName != null ? !podName.equals(that.podName) : that.podName != null) return false;
if (startIP != null ? !startIP.equals(that.startIP) : that.startIP != null) return false;
if (vlan != null ? !vlan.equals(that.vlan) : that.vlan != null) return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (id ^ (id >>> 32));
result = 31 * result + (description != null ? description.hashCode() : 0);
result = 31 * result + (forVirtualNetwork ? 1 : 0);
result = 31 * result + (int) (zoneId ^ (zoneId >>> 32));
result = 31 * result + (vlan != null ? vlan.hashCode() : 0);
result = 31 * result + (account != null ? account.hashCode() : 0);
result = 31 * result + (int) (domainId ^ (domainId >>> 32));
result = 31 * result + (domain != null ? domain.hashCode() : 0);
result = 31 * result + (int) (podId ^ (podId >>> 32));
result = 31 * result + (podName != null ? podName.hashCode() : 0);
result = 31 * result + (gateway != null ? gateway.hashCode() : 0);
result = 31 * result + (netmask != null ? netmask.hashCode() : 0);
result = 31 * result + (startIP != null ? startIP.hashCode() : 0);
result = 31 * result + (endIP != null ? endIP.hashCode() : 0);
result = 31 * result + (int) (networkId ^ (networkId >>> 32));
return result;
}
@Override
public String toString() {
return "VlanIPRange{" +
"id=" + id +
", description='" + description + '\'' +
", forVirtualNetwork=" + forVirtualNetwork +
", zoneId=" + zoneId +
", vlan='" + vlan + '\'' +
", account='" + account + '\'' +
", domainId=" + domainId +
", domain='" + domain + '\'' +
", podId=" + podId +
", podName='" + podName + '\'' +
", gateway='" + gateway + '\'' +
", netmask='" + netmask + '\'' +
", startIP='" + startIP + '\'' +
", endIP='" + endIP + '\'' +
", networkId=" + networkId +
'}';
}
@Override
public int compareTo(VlanIPRange other) {
return Long.valueOf(this.id).compareTo(other.id);
}
}

View File

@ -26,7 +26,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.Account; 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.cloudstack.options.ListAccountsOptions;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.OnlyElement; 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" /> * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface AccountAsyncClient { 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.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.PublicIPAddress; 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.functions.ReturnVoidOnNotFoundOr404OrUnableToFindAccountOwner;
import org.jclouds.cloudstack.options.AssociateIPAddressOptions; import org.jclouds.cloudstack.options.AssociateIPAddressOptions;
import org.jclouds.cloudstack.options.ListPublicIPAddressesOptions; 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" /> * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface AddressAsyncClient { public interface AddressAsyncClient {

View File

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

View File

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

View File

@ -21,7 +21,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Account; import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; 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.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams; import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters; 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" * "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") @QueryParams(keys = "response", values = "json")
public interface DomainAccountAsyncClient extends AccountAsyncClient { public interface DomainAccountAsyncClient extends AccountAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Domain; 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.ListDomainChildrenOptions;
import org.jclouds.cloudstack.options.ListDomainsOptions; import org.jclouds.cloudstack.options.ListDomainsOptions;
import org.jclouds.rest.annotations.ExceptionParser; 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" * "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") @QueryParams(keys = "response", values = "json")
public interface DomainDomainAsyncClient { 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.binders.ResourceLimitToQueryParams;
import org.jclouds.cloudstack.domain.ResourceLimit; 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.BinderParam;
import org.jclouds.rest.annotations.QueryParams; import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters; 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" * "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") @QueryParams(keys = "response", values = "json")
public interface DomainLimitAsyncClient extends LimitAsyncClient { public interface DomainLimitAsyncClient extends LimitAsyncClient {
/** /**

View File

@ -21,7 +21,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.User; 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.cloudstack.options.ListUsersOptions;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams; 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" * "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") @QueryParams(keys = "response", values = "json")
public interface DomainUserAsyncClient { public interface DomainUserAsyncClient {

View File

@ -25,7 +25,7 @@ import java.util.Set;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Event; 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.functions.ParseEventTypesFromHttpResponse;
import org.jclouds.cloudstack.options.ListEventsOptions; import org.jclouds.cloudstack.options.ListEventsOptions;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
@ -43,7 +43,7 @@ import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
* @see org.jclouds.cloudstack.features.AccountClient * @see org.jclouds.cloudstack.features.AccountClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" /> * @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") @QueryParams(keys = "response", values = "json")
public interface EventAsyncClient { 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.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.FirewallRule; import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.PortForwardingRule; 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.CreateFirewallRuleOptions;
import org.jclouds.cloudstack.options.ListFirewallRulesOptions; import org.jclouds.cloudstack.options.ListFirewallRulesOptions;
import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions; import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions;
@ -52,7 +52,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see FirewallClient * @see FirewallClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" /> * @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") @QueryParams(keys = "response", values = "json")
public interface FirewallAsyncClient { public interface FirewallAsyncClient {

View File

@ -24,7 +24,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.Account; 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.CreateAccountOptions;
import org.jclouds.cloudstack.options.UpdateAccountOptions; import org.jclouds.cloudstack.options.UpdateAccountOptions;
import org.jclouds.rest.annotations.ExceptionParser; 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" * "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") @QueryParams(keys = "response", values = "json")
public interface GlobalAccountAsyncClient extends DomainAccountAsyncClient { public interface GlobalAccountAsyncClient extends DomainAccountAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Alert; 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.cloudstack.options.ListAlertsOptions;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams; 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" * "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") @QueryParams(keys = "response", values = "json")
public interface GlobalAlertAsyncClient { public interface GlobalAlertAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Capacity; 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.cloudstack.options.ListCapacityOptions;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams; 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" * "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") @QueryParams(keys = "response", values = "json")
public interface GlobalCapacityAsyncClient { public interface GlobalCapacityAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.ConfigurationEntry; 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.cloudstack.options.ListConfigurationEntriesOptions;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.OnlyElement; 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" * "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") @QueryParams(keys = "response", values = "json")
public interface GlobalConfigurationAsyncClient extends ConfigurationAsyncClient { public interface GlobalConfigurationAsyncClient extends ConfigurationAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Domain; 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.CreateDomainOptions;
import org.jclouds.cloudstack.options.UpdateDomainOptions; import org.jclouds.cloudstack.options.UpdateDomainOptions;
import org.jclouds.rest.annotations.ExceptionParser; 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" * "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") @QueryParams(keys = "response", values = "json")
public interface GlobalDomainAsyncClient extends DomainDomainAsyncClient { public interface GlobalDomainAsyncClient extends DomainDomainAsyncClient {

View File

@ -21,7 +21,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Cluster; import org.jclouds.cloudstack.domain.Cluster;
import org.jclouds.cloudstack.domain.Host; 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.AddClusterOptions;
import org.jclouds.cloudstack.options.AddHostOptions; import org.jclouds.cloudstack.options.AddHostOptions;
import org.jclouds.cloudstack.options.AddSecondaryStorageOptions; 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" /> * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html" />
* @author Andrei Savu * @author Andrei Savu
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface GlobalHostAsyncClient { 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.DiskOffering;
import org.jclouds.cloudstack.domain.NetworkOffering; import org.jclouds.cloudstack.domain.NetworkOffering;
import org.jclouds.cloudstack.domain.ServiceOffering; 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.CreateDiskOfferingOptions;
import org.jclouds.cloudstack.options.CreateServiceOfferingOptions; import org.jclouds.cloudstack.options.CreateServiceOfferingOptions;
import org.jclouds.cloudstack.options.UpdateDiskOfferingOptions; 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" /> * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html" />
* @author Andrei Savu * @author Andrei Savu
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface GlobalOfferingAsyncClient extends OfferingAsyncClient { public interface GlobalOfferingAsyncClient extends OfferingAsyncClient {

View File

@ -20,7 +20,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Pod; 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.CreatePodOptions;
import org.jclouds.cloudstack.options.ListPodsOptions; import org.jclouds.cloudstack.options.ListPodsOptions;
import org.jclouds.cloudstack.options.UpdatePodOptions; 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" * "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") @QueryParams(keys = "response", values = "json")
public interface GlobalPodAsyncClient { public interface GlobalPodAsyncClient {

View File

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

View File

@ -21,7 +21,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.JobResult; import org.jclouds.cloudstack.domain.JobResult;
import org.jclouds.cloudstack.domain.UsageRecord; 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.functions.DateToYyyyMmDd;
import org.jclouds.cloudstack.options.GenerateUsageRecordsOptions; import org.jclouds.cloudstack.options.GenerateUsageRecordsOptions;
import org.jclouds.cloudstack.options.ListUsageRecordsOptions; 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" /> * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html" />
* @author Richard Downer * @author Richard Downer
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface GlobalUsageAsyncClient { 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.collections.Integration;
import org.jclouds.cloudstack.domain.ApiKeyPair; import org.jclouds.cloudstack.domain.ApiKeyPair;
import org.jclouds.cloudstack.domain.User; 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.CreateUserOptions;
import org.jclouds.cloudstack.options.UpdateUserOptions; import org.jclouds.cloudstack.options.UpdateUserOptions;
import org.jclouds.rest.annotations.Endpoint; 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" * "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") @QueryParams(keys = "response", values = "json")
public interface GlobalUserAsyncClient extends DomainUserAsyncClient { public interface GlobalUserAsyncClient extends DomainUserAsyncClient {

View File

@ -0,0 +1,104 @@
/**
* 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.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.VlanIPRange;
import org.jclouds.cloudstack.filters.AuthenticationFilter;
import org.jclouds.cloudstack.options.CreateVlanIPRangeOptions;
import org.jclouds.cloudstack.options.ListVlanIPRangesOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.OnlyElement;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.Set;
/**
* Provides asynchronous access to cloudstack via their REST API.
* <p/>
*
* @see org.jclouds.cloudstack.features.GlobalVlanClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html" />
* @author Richard Downer
*/
@RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json")
public interface GlobalVlanAsyncClient {
/**
* Get the details of an IP range by its id.
* @param id the required IP range.
* @return the requested IP range.
*/
@GET
@QueryParams(keys = "command", values = "listVlanIpRanges")
@SelectJson("vlaniprange")
@OnlyElement
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<VlanIPRange> getVlanIPRange(@QueryParam("id") long id);
/**
* Lists all VLAN IP ranges.
*
* @param options optional arguments.
* @return the list of IP ranges that match the criteria.
*/
@GET
@QueryParams(keys = "command", values = "listVlanIpRanges")
@SelectJson("vlaniprange")
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<VlanIPRange>> listVlanIPRanges(ListVlanIPRangesOptions... options);
/**
* Creates a VLAN IP range.
*
* @param startIP the beginning IP address in the VLAN IP range
* @param endIP the ending IP address in the VLAN IP range
* @param options optional arguments
* @return the newly-create IP range.
*/
@GET
@QueryParams(keys = "command", values = "createVlanIpRange")
@SelectJson("vlaniprange")
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<VlanIPRange> createVlanIPRange(@QueryParam("startip") String startIP, @QueryParam("endip") String endIP, CreateVlanIPRangeOptions... options);
/**
* Deletes a VLAN IP range.
* @param rangeId the id of the VLAN IP range
* @return void
*/
@GET
@QueryParams(keys = "command", values = "deleteVlanIpRange")
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteVlanIPRange(@QueryParam("id") long rangeId);
}

View File

@ -0,0 +1,70 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.features;
import org.jclouds.cloudstack.domain.VlanIPRange;
import org.jclouds.cloudstack.options.CreateVlanIPRangeOptions;
import org.jclouds.cloudstack.options.ListVlanIPRangesOptions;
import org.jclouds.concurrent.Timeout;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Provides synchronous access to CloudStack VLAN features.
* <p/>
*
* @see GlobalOfferingAsyncClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html" />
* @author Richard Downer
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface GlobalVlanClient {
/**
* Get the details of an IP range by its id.
* @param id the required IP range.
* @return the requested IP range.
*/
VlanIPRange getVlanIPRange(long id);
/**
* Lists all VLAN IP ranges.
*
* @param options optional arguments.
* @return the list of IP ranges that match the criteria.
*/
Set<VlanIPRange> listVlanIPRanges(ListVlanIPRangesOptions... options);
/**
* Creates a VLAN IP range.
*
* @param startIP the beginning IP address in the VLAN IP range
* @param endIP the ending IP address in the VLAN IP range
* @param options optional arguments
* @return the newly-create IP range.
*/
VlanIPRange createVlanIPRange(String startIP, String endIP, CreateVlanIPRangeOptions... options);
/**
* Deletes a VLAN IP range.
* @param rangeId the id of the VLAN IP range
*/
void deleteVlanIPRange(long rangeId);
}

View File

@ -21,7 +21,7 @@ package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.NetworkType; import org.jclouds.cloudstack.domain.NetworkType;
import org.jclouds.cloudstack.domain.Zone; 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.CreateZoneOptions;
import org.jclouds.cloudstack.options.UpdateZoneOptions; import org.jclouds.cloudstack.options.UpdateZoneOptions;
import org.jclouds.rest.annotations.ExceptionParser; 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" * "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") @QueryParams(keys = "response", values = "json")
public interface GlobalZoneAsyncClient extends ZoneAsyncClient { public interface GlobalZoneAsyncClient extends ZoneAsyncClient {

View File

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

View File

@ -23,7 +23,7 @@ import java.util.Set;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.QueryParam; 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.cloudstack.functions.ParseNamesFromHttpResponse;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams; 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" /> * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface HypervisorAsyncClient { 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.ExtractMode;
import org.jclouds.cloudstack.domain.ISO; import org.jclouds.cloudstack.domain.ISO;
import org.jclouds.cloudstack.domain.ISOPermissions; 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.AccountInDomainOptions;
import org.jclouds.cloudstack.options.DeleteISOOptions; import org.jclouds.cloudstack.options.DeleteISOOptions;
import org.jclouds.cloudstack.options.ExtractISOOptions; 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 * @see http://download.cloud.com/releases/2.2.12/api/TOC_User.html
* @author Richard Downer * @author Richard Downer
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
@SkipEncoding({'/', ','}) @SkipEncoding({'/', ','})
public interface ISOAsyncClient { public interface ISOAsyncClient {

View File

@ -25,7 +25,7 @@ import javax.ws.rs.GET;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.ResourceLimit; 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.cloudstack.options.ListResourceLimitsOptions;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams; 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" * 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") @QueryParams(keys = "response", values = "json")
public interface LimitAsyncClient { 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;
import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm; import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm;
import org.jclouds.cloudstack.domain.VirtualMachine; 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.CreateLoadBalancerRuleOptions;
import org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions; import org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions;
import org.jclouds.cloudstack.options.UpdateLoadBalancerRuleOptions; 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" /> * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface LoadBalancerAsyncClient { 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.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.IPForwardingRule; 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.CreateIPForwardingRuleOptions;
import org.jclouds.cloudstack.options.ListIPForwardingRulesOptions; import org.jclouds.cloudstack.options.ListIPForwardingRulesOptions;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
@ -51,7 +51,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* /> * />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface NATAsyncClient { public interface NATAsyncClient {

View File

@ -26,7 +26,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.Network; 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.CreateNetworkOptions;
import org.jclouds.cloudstack.options.ListNetworksOptions; import org.jclouds.cloudstack.options.ListNetworksOptions;
import org.jclouds.rest.annotations.ExceptionParser; 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" /> * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface NetworkAsyncClient { 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.DiskOffering;
import org.jclouds.cloudstack.domain.NetworkOffering; import org.jclouds.cloudstack.domain.NetworkOffering;
import org.jclouds.cloudstack.domain.ServiceOffering; 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.ListDiskOfferingsOptions;
import org.jclouds.cloudstack.options.ListNetworkOfferingsOptions; import org.jclouds.cloudstack.options.ListNetworkOfferingsOptions;
import org.jclouds.cloudstack.options.ListServiceOfferingsOptions; 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" /> * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface OfferingAsyncClient { public interface OfferingAsyncClient {

View File

@ -26,7 +26,7 @@ import java.util.Set;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.SshKeyPair; 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.cloudstack.options.ListSSHKeyPairsOptions;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.OnlyElement; 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" * 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") @QueryParams(keys = "response", values = "json")
public interface SSHKeyPairAsyncClient { 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.BindAccountSecurityGroupPairsToIndexedQueryParams;
import org.jclouds.cloudstack.binders.BindCIDRsToCommaDelimitedQueryParam; import org.jclouds.cloudstack.binders.BindCIDRsToCommaDelimitedQueryParam;
import org.jclouds.cloudstack.domain.SecurityGroup; 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.AccountInDomainOptions;
import org.jclouds.cloudstack.options.ListSecurityGroupsOptions; import org.jclouds.cloudstack.options.ListSecurityGroupsOptions;
import org.jclouds.rest.annotations.BinderParam; 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" /> * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface SecurityGroupAsyncClient { public interface SecurityGroupAsyncClient {

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.features;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.cloudstack.functions.ParseLoginResponseFromHttpResponse;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Cloudstack Sessions
* <p/>
*
* @see org.jclouds.cloudstack.features.SessionClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Andrei Savu
*/
@QueryParams(keys = "response", values = "json")
public interface SessionAsyncClient {
/**
* @see SessionClient#loginUserInDomainWithHashOfPassword
*/
@GET
@QueryParams(keys = "command", values = "login")
@ResponseParser(ParseLoginResponseFromHttpResponse.class)
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<LoginResponse> loginUserInDomainWithHashOfPassword(@QueryParam("username") String userName,
@QueryParam("domain") String domain, @QueryParam("password") String hashedPassword);
/**
* @see SessionClient#logoutUser
*/
@GET
@QueryParams(keys = "command", values = "logout")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> logoutUser(@QueryParam("sessionkey") String sessionKey);
}

View File

@ -0,0 +1,63 @@
/**
* 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.features;
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.concurrent.Timeout;
/**
* Provides synchronous access to CloudStack Sessions
* <p/>
*
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Andrei Savu
*/
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
public interface SessionClient {
/**
* Logs a user into Cloudstack. A successful login attempt will generate a JSESSIONID
* cookie value that can be passed in subsequent Query command calls until the "logout"
* command has been issued or the session has expired.
*
*
*
* @param userName
* user account name
* @param domain
* domain name, if empty defaults to ROOT
* @param hashedPassword
* hashed password (by default MD5)
* @return
* login response with session key or null
*/
LoginResponse loginUserInDomainWithHashOfPassword(String userName, String domain, String hashedPassword);
/**
* Logs out the user by invalidating the session key
*
* @param sessionKey
* user session key
*/
void logoutUser(String sessionKey);
}

View File

@ -25,7 +25,7 @@ import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.Snapshot; import org.jclouds.cloudstack.domain.Snapshot;
import org.jclouds.cloudstack.domain.SnapshotPolicy; import org.jclouds.cloudstack.domain.SnapshotPolicy;
import org.jclouds.cloudstack.domain.SnapshotPolicySchedule; 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.CreateSnapshotOptions;
import org.jclouds.cloudstack.options.ListSnapshotPoliciesOptions; import org.jclouds.cloudstack.options.ListSnapshotPoliciesOptions;
import org.jclouds.cloudstack.options.ListSnapshotsOptions; 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 * @see http://download.cloud.com/releases/2.2.0/api/TOC_User.html
* @author Richard Downer * @author Richard Downer
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface SnapshotAsyncClient { 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.Template;
import org.jclouds.cloudstack.domain.TemplateMetadata; import org.jclouds.cloudstack.domain.TemplateMetadata;
import org.jclouds.cloudstack.domain.TemplatePermission; 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.AccountInDomainOptions;
import org.jclouds.cloudstack.options.CreateTemplateOptions; import org.jclouds.cloudstack.options.CreateTemplateOptions;
import org.jclouds.cloudstack.options.DeleteTemplateOptions; import org.jclouds.cloudstack.options.DeleteTemplateOptions;
@ -63,7 +63,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* /> * />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(AuthenticationFilter.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
@SkipEncoding(',') @SkipEncoding(',')
public interface TemplateAsyncClient { public interface TemplateAsyncClient {

View File

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

View File

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

View File

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

View File

@ -0,0 +1,47 @@
package org.jclouds.cloudstack.filters;
import static org.jclouds.http.utils.ModifyRequest.addQueryParam;
import static org.jclouds.http.utils.ModifyRequest.replaceHeader;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpRequest;
import com.google.common.base.Supplier;
import com.google.common.net.HttpHeaders;
/**
*
* @author Andrei Savu, Adrian Cole
* @see <a href="http://docs.cloud.com/CloudStack_Documentation/Customizing_the_CloudStack_UI#Cross_Site_Request_Forgery_%28CSRF%29"
* />
*/
@Singleton
public class AddSessionKeyAndJSessionIdToRequest implements AuthenticationFilter {
private final Supplier<LoginResponse> loginResponseSupplier;
private final Provider<UriBuilder> uriBuilderProvider;
@Inject
public AddSessionKeyAndJSessionIdToRequest(Supplier<LoginResponse> loginResponseSupplier,
Provider<UriBuilder> uriBuilderProvider) {
this.loginResponseSupplier = loginResponseSupplier;
this.uriBuilderProvider = uriBuilderProvider;
}
@Override
public HttpRequest filter(HttpRequest request) throws HttpException {
LoginResponse loginResponse = loginResponseSupplier.get();
request = replaceHeader(request, HttpHeaders.COOKIE, "JSESSIONID=" + loginResponse.getJSessionId());
request = addQueryParam(request, "sessionkey", loginResponse.getSessionKey(), uriBuilderProvider.get());
return request;
}
}

View File

@ -16,26 +16,20 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.glesys.functions; package org.jclouds.cloudstack.filters;
import javax.inject.Inject; import org.jclouds.http.HttpRequestFilter;
import javax.inject.Singleton;
import org.jclouds.glesys.domain.ServerDetails; import com.google.inject.ImplementedBy;
import org.jclouds.json.internal.GsonWrapper;
import com.google.inject.TypeLiteral;
/** /**
* Marker interface that determines how we authenticate http requests in cloudstack. default to sign
* requests as opposed to login.
*
* @author Adrian Cole * @author Adrian Cole
*
*/ */
@Singleton @ImplementedBy(QuerySigner.class)
public class MergeArgumentsAndReturnServerDetails extends MergeArgumentsAndParse<ServerDetails> { public interface AuthenticationFilter extends HttpRequestFilter {
@Inject
public MergeArgumentsAndReturnServerDetails(GsonWrapper json) {
super(json, new TypeLiteral<ServerDetails>() {
}, "server");
}
} }

View File

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

View File

@ -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.cloudstack.functions;
import com.google.common.base.Function;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.cloudstack.features.SessionClient;
import org.jclouds.crypto.CryptoStreams;
import org.jclouds.domain.Credentials;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.File;
@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 = ""; // empty = ROOT domain
// 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,41 @@
package org.jclouds.cloudstack.functions;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.inject.Inject;
import com.google.inject.TypeLiteral;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseFirstJsonValueNamed;
import org.jclouds.json.internal.GsonWrapper;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.get;
import static com.google.common.collect.Iterables.getOnlyElement;
/**
* @author Andrei Savu
*/
public class ParseLoginResponseFromHttpResponse implements Function<HttpResponse, LoginResponse> {
private ParseFirstJsonValueNamed<LoginResponse> parser;
@Inject
ParseLoginResponseFromHttpResponse(GsonWrapper gson) {
this.parser = new ParseFirstJsonValueNamed<LoginResponse>(checkNotNull(gson, "gsonWrapper"),
new TypeLiteral<LoginResponse>(){}, "loginresponse");
}
@Override
public LoginResponse apply(HttpResponse response) {
checkNotNull(response, "response");
LoginResponse login = parser.apply(response);
checkNotNull(login, "loginResponse");
String jSessionId = get(Splitter.on("=").split(get(Splitter.on(";").trimResults().split(
getOnlyElement(response.getHeaders().get("Set-Cookie"))), 0)), 1);
return LoginResponse.builder().copyOf(login).jSessionId(jSessionId).build();
}
}

View File

@ -18,11 +18,8 @@
*/ */
package org.jclouds.cloudstack.handlers; package org.jclouds.cloudstack.handlers;
import java.io.IOException; import com.google.common.base.Throwables;
import com.google.common.io.Closeables;
import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
@ -32,8 +29,9 @@ import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.util.Strings2; import org.jclouds.util.Strings2;
import com.google.common.base.Throwables; import javax.annotation.Resource;
import com.google.common.io.Closeables; import javax.inject.Singleton;
import java.io.IOException;
/** /**
* *
@ -57,6 +55,7 @@ public class CloudStackErrorHandler implements HttpErrorHandler {
case 400: case 400:
exception = new IllegalArgumentException(message, exception); exception = new IllegalArgumentException(message, exception);
break; break;
case 531:
case 401: case 401:
exception = new AuthorizationException(message, exception); exception = new AuthorizationException(message, exception);
break; break;

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,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.cloudstack.options;
import com.google.common.collect.ImmutableSet;
/**
* Options to the createVlanIPRange API call.
*
* @author Richard Downer
*/
public class CreateVlanIPRangeOptions extends AccountInDomainOptions {
public static class Builder {
public static CreateVlanIPRangeOptions accountInDomain(String account, long domain) {
return new CreateVlanIPRangeOptions().accountInDomain(account, domain);
}
public static CreateVlanIPRangeOptions domainId(long domainId) {
return new CreateVlanIPRangeOptions().domainId(domainId);
}
public static CreateVlanIPRangeOptions forVirtualNetwork(boolean forVirtualNetwork) {
return new CreateVlanIPRangeOptions().forVirtualNetwork(forVirtualNetwork);
}
public static CreateVlanIPRangeOptions zoneId(long zoneId) {
return new CreateVlanIPRangeOptions().zoneId(zoneId);
}
public static CreateVlanIPRangeOptions vlan(long vlan) {
return new CreateVlanIPRangeOptions().vlan(vlan);
}
public static CreateVlanIPRangeOptions vlan(String vlan) {
return new CreateVlanIPRangeOptions().vlan(vlan);
}
public static CreateVlanIPRangeOptions podId(long podId) {
return new CreateVlanIPRangeOptions().podId(podId);
}
public static CreateVlanIPRangeOptions gateway(String gateway) {
return new CreateVlanIPRangeOptions().gateway(gateway);
}
public static CreateVlanIPRangeOptions netmask(String netmask) {
return new CreateVlanIPRangeOptions().netmask(netmask);
}
public static CreateVlanIPRangeOptions networkId(long networkId) {
return new CreateVlanIPRangeOptions().networkId(networkId);
}
}
@Override
public CreateVlanIPRangeOptions accountInDomain(String account, long domain) {
return (CreateVlanIPRangeOptions) super.accountInDomain(account, domain);
}
@Override
public CreateVlanIPRangeOptions domainId(long domainId) {
return (CreateVlanIPRangeOptions) super.domainId(domainId);
}
public CreateVlanIPRangeOptions forVirtualNetwork(boolean forVirtualNetwork) {
this.queryParameters.replaceValues("forvirtualnetwork", ImmutableSet.of(forVirtualNetwork+""));
return this;
}
public CreateVlanIPRangeOptions zoneId(long zoneId) {
this.queryParameters.replaceValues("zoneid", ImmutableSet.of(zoneId+""));
return this;
}
public CreateVlanIPRangeOptions vlan(long vlan) {
this.queryParameters.replaceValues("vlan", ImmutableSet.of(vlan+""));
return this;
}
public CreateVlanIPRangeOptions vlan(String vlan) {
this.queryParameters.replaceValues("vlan", ImmutableSet.of(vlan));
return this;
}
public CreateVlanIPRangeOptions podId(long podId) {
this.queryParameters.replaceValues("podid", ImmutableSet.of(podId+""));
return this;
}
public CreateVlanIPRangeOptions gateway(String gateway) {
this.queryParameters.replaceValues("gateway", ImmutableSet.of(gateway));
return this;
}
public CreateVlanIPRangeOptions netmask(String netmask) {
this.queryParameters.replaceValues("netmask", ImmutableSet.of(netmask));
return this;
}
public CreateVlanIPRangeOptions networkId(long networkId) {
this.queryParameters.replaceValues("networkid", ImmutableSet.of(networkId+""));
return this;
}
}

View File

@ -0,0 +1,122 @@
/**
* 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.options;
import com.google.common.collect.ImmutableSet;
/**
* Options to the listVLANIPRanges() API call
*
* @author Richard Downer
*/
public class ListVlanIPRangesOptions extends AccountInDomainOptions {
public static class Builder {
public static ListVlanIPRangesOptions accountInDomain(String account, long domainId) {
return new ListVlanIPRangesOptions().accountInDomain(account, domainId);
}
public static ListVlanIPRangesOptions domainId(long domainId) {
return new ListVlanIPRangesOptions().domainId(domainId);
}
public static ListVlanIPRangesOptions forVirtualNetwork(boolean forVirtualNetwork) {
return new ListVlanIPRangesOptions().forVirtualNetwork(forVirtualNetwork);
}
public static ListVlanIPRangesOptions id(long id) {
return new ListVlanIPRangesOptions().id(id);
}
public static ListVlanIPRangesOptions keyword(String keyword) {
return new ListVlanIPRangesOptions().keyword(keyword);
}
public static ListVlanIPRangesOptions networkId(long networkId) {
return new ListVlanIPRangesOptions().networkId(networkId);
}
public static ListVlanIPRangesOptions podId(long podId) {
return new ListVlanIPRangesOptions().podId(podId);
}
public static ListVlanIPRangesOptions vlan(String vlan) {
return new ListVlanIPRangesOptions().vlan(vlan);
}
public static ListVlanIPRangesOptions vlan(long vlan) {
return new ListVlanIPRangesOptions().vlan(vlan+"");
}
public static ListVlanIPRangesOptions zoneId(long zoneId) {
return new ListVlanIPRangesOptions().zoneId(zoneId);
}
}
@Override
public ListVlanIPRangesOptions accountInDomain(String account, long domainId) {
return (ListVlanIPRangesOptions) super.accountInDomain(account, domainId);
}
@Override
public ListVlanIPRangesOptions domainId(long domainId) {
return (ListVlanIPRangesOptions) super.domainId(domainId);
}
public ListVlanIPRangesOptions forVirtualNetwork(boolean forVirtualNetwork) {
this.queryParameters.replaceValues("forvirtualnetwork", ImmutableSet.of(forVirtualNetwork+""));
return this;
}
public ListVlanIPRangesOptions id(long id) {
this.queryParameters.replaceValues("id", ImmutableSet.of(id+""));
return this;
}
public ListVlanIPRangesOptions keyword(String keyword) {
this.queryParameters.replaceValues("keyword", ImmutableSet.of(keyword));
return this;
}
public ListVlanIPRangesOptions networkId(long networkId) {
this.queryParameters.replaceValues("networkid", ImmutableSet.of(networkId+""));
return this;
}
public ListVlanIPRangesOptions podId(long podId) {
this.queryParameters.replaceValues("podid", ImmutableSet.of(podId+""));
return this;
}
public ListVlanIPRangesOptions vlan(String vlan) {
this.queryParameters.replaceValues("vlan", ImmutableSet.of(vlan));
return this;
}
public ListVlanIPRangesOptions vlan(long vlan) {
this.queryParameters.replaceValues("vlan", ImmutableSet.of(vlan+""));
return this;
}
public ListVlanIPRangesOptions zoneId(long zoneId) {
this.queryParameters.replaceValues("zoneid", ImmutableSet.of(zoneId+""));
return this;
}
}

View File

@ -0,0 +1,106 @@
/**
* 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.util;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
import org.jclouds.Constants;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.ApiKeyPair;
import org.jclouds.cloudstack.domain.User;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.rest.RestContextFactory;
import java.net.URI;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* @author Andrei Savu
*/
public class ApiKeyPairs {
private final static String PROVIDER = "cloudstack";
/**
* Retrieve the API key pair for a given CloudStack user
*
* @param endpoint
* CloudStack API endpoint (e.g. http://72.52.126.25/client/api/)
* @param username
* User account name
* @param password
* User password
* @param domain
* Domain name. If empty defaults to ROOT
* @throws NoSuchElementException, AuthorizationException
* @return
*/
public static ApiKeyPair loginToEndpointAsUsernameInDomainWithPasswordAndReturnApiKeyPair(
URI endpoint, String username, String password, String domain) {
ComputeServiceContext context = null;
try {
context = new ComputeServiceContextFactory(setupRestProperties()).
createContext(PROVIDER, ImmutableSet.<Module>of(), setupProperties(endpoint, username, password, domain));
CloudStackClient client = CloudStackClient.class.cast(context.getProviderSpecificContext().getApi());
Set<Account> listOfAccounts = client.getAccountClient().listAccounts();
domain = (domain.equals("") || domain.equals("/")) ? "ROOT" : domain;
for (Account account : listOfAccounts) {
for (User user : account.getUsers()) {
if (user.getName().equals(username) && user.getDomain().equals(domain)) {
return ApiKeyPair.builder().apiKey(user.getApiKey())
.secretKey(user.getSecretKey()).build();
}
}
}
throw new NoSuchElementException("Unable to find API keypair for user " + username);
} finally {
if (context != null)
context.close();
}
}
private static Properties setupRestProperties() {
return RestContextFactory.getPropertiesFromResource("/rest.properties");
}
private static Properties setupProperties(URI endpoint, String username, String password, String domain) {
Properties overrides = new Properties();
overrides.put(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
overrides.put(Constants.PROPERTY_RELAX_HOSTNAME, "true");
overrides.put("jclouds.cloudstack.credential-type", "passwordCredentials");
overrides.put(PROVIDER + ".endpoint", checkNotNull(endpoint, "endpoint").toASCIIString());
overrides.put(PROVIDER + ".identity",
String.format("%s/%s", checkNotNull(domain, "domain"), checkNotNull(username, "username")));
overrides.put(PROVIDER + ".credential", checkNotNull(password, "password"));
return overrides;
}
}

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 CloudStackProperties#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,35 +18,38 @@
*/ */
package org.jclouds.cloudstack.compute.functions; package org.jclouds.cloudstack.compute.functions;
import static org.testng.Assert.assertEquals;
import java.net.UnknownHostException;
import java.util.Set;
import org.jclouds.cloudstack.compute.functions.VirtualMachineToNodeMetadata.FindHardwareForVirtualMachine;
import org.jclouds.cloudstack.compute.functions.VirtualMachineToNodeMetadata.FindImageForVirtualMachine;
import org.jclouds.cloudstack.compute.functions.VirtualMachineToNodeMetadata.FindLocationForVirtualMachine;
import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.parse.ListVirtualMachinesResponseTest;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Location;
import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import org.jclouds.cloudstack.compute.functions.VirtualMachineToNodeMetadata.FindImageForVirtualMachine;
import org.jclouds.cloudstack.compute.functions.VirtualMachineToNodeMetadata.FindLocationForVirtualMachine;
import org.jclouds.cloudstack.domain.GuestIPType;
import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.NIC;
import org.jclouds.cloudstack.domain.TrafficType;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.parse.ListVirtualMachinesResponseTest;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.domain.Location;
import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test;
import java.net.UnknownHostException;
import java.util.Set;
import static org.testng.Assert.assertEquals;
/** /**
* @author Adrian Cole * @author Adrian Cole, Andrei Savu
*/ */
@Test(groups = "unit", testName = "VirtualMachineToNodeMetadataTest") @Test(groups = "unit", testName = "VirtualMachineToNodeMetadataTest")
public class VirtualMachineToNodeMetadataTest { public class VirtualMachineToNodeMetadataTest {
@ -55,15 +58,12 @@ public class VirtualMachineToNodeMetadataTest {
public void testApplyWhereVirtualMachineWithIPForwardingRule() throws UnknownHostException { public void testApplyWhereVirtualMachineWithIPForwardingRule() throws UnknownHostException {
Supplier<Set<? extends Location>> locationSupplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet Supplier<Set<? extends Location>> locationSupplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(ZoneToLocationTest.one, ZoneToLocationTest.two)); .<Location>of(ZoneToLocationTest.one, ZoneToLocationTest.two));
Supplier<Set<? extends Hardware>> hardwareSupplier = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(ServiceOfferingToHardwareTest.one, ServiceOfferingToHardwareTest.two));
Supplier<Set<? extends Image>> imageSupplier = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet Supplier<Set<? extends Image>> imageSupplier = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet
.<Image> of(TemplateToImageTest.one, TemplateToImageTest.two)); .<Image>of(TemplateToImageTest.one, TemplateToImageTest.two));
VirtualMachineToNodeMetadata parser = new VirtualMachineToNodeMetadata(new FindLocationForVirtualMachine( VirtualMachineToNodeMetadata parser = new VirtualMachineToNodeMetadata(new FindLocationForVirtualMachine(
locationSupplier), new FindHardwareForVirtualMachine(hardwareSupplier), new FindImageForVirtualMachine( locationSupplier), new FindImageForVirtualMachine(
imageSupplier), CacheBuilder.newBuilder().<Long, Set<IPForwardingRule>> build( imageSupplier), CacheBuilder.newBuilder().<Long, Set<IPForwardingRule>> build(
new CacheLoader<Long, Set<IPForwardingRule>>() { new CacheLoader<Long, Set<IPForwardingRule>>() {
@ -84,24 +84,85 @@ public class VirtualMachineToNodeMetadataTest {
new NodeMetadataBuilder().id("54").providerId("54").name("i-3-54-VM").group("i-3") new NodeMetadataBuilder().id("54").providerId("54").name("i-3-54-VM").group("i-3")
.location(ZoneToLocationTest.one).state(NodeState.PENDING).hostname("i-3-54-VM") .location(ZoneToLocationTest.one).state(NodeState.PENDING).hostname("i-3-54-VM")
.privateAddresses(ImmutableSet.of("10.1.1.18")).publicAddresses(ImmutableSet.of("1.1.1.1")) .privateAddresses(ImmutableSet.of("10.1.1.18")).publicAddresses(ImmutableSet.of("1.1.1.1"))
.hardware(ServiceOfferingToHardwareTest.one).imageId(TemplateToImageTest.one.getId()) .hardware(addHypervisor(ServiceOfferingToHardwareTest.one, "XenServer"))
.imageId(TemplateToImageTest.one.getId())
.operatingSystem(TemplateToImageTest.one.getOperatingSystem()).build().toString()); .operatingSystem(TemplateToImageTest.one.getOperatingSystem()).build().toString());
} }
@Test
public void testApplyWhereVirtualMachineHasNoIpForwardingRuleAndAPublicIP() throws UnknownHostException {
Supplier<Set<? extends Location>> locationSupplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location>of(ZoneToLocationTest.one, ZoneToLocationTest.two));
Supplier<Set<? extends Image>> imageSupplier = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet
.<Image>of(TemplateToImageTest.one, TemplateToImageTest.two));
VirtualMachineToNodeMetadata parser = new VirtualMachineToNodeMetadata(new FindLocationForVirtualMachine(
locationSupplier), new FindImageForVirtualMachine(
imageSupplier), CacheBuilder.newBuilder().<Long, Set<IPForwardingRule>> build(
new CacheLoader<Long, Set<IPForwardingRule>>() {
@Override
public Set<IPForwardingRule> load(Long arg0) throws Exception {
return ImmutableSet.of();
}
}));
VirtualMachine guest =VirtualMachine.builder()
.id(54)
.name("i-3-54-VM")
.displayName("i-3-54-VM")
.account("adrian")
.domainId(1)
.domain("ROOT")
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-02-16T14:28:37-0800"))
.state(VirtualMachine.State.STARTING)
.isHAEnabled(false)
.zoneId(1)
.zoneName("San Jose 1")
.templateId(2)
.templateName("CentOS 5.3(64-bit) no GUI (XenServer)")
.templateDisplayText("CentOS 5.3(64-bit) no GUI (XenServer)")
.passwordEnabled(false)
.serviceOfferingId(1)
.serviceOfferingName("Small Instance")
.cpuCount(1)
.cpuSpeed(500)
.memory(512)
.guestOSId(11)
.rootDeviceId(0)
.rootDeviceType("NetworkFilesystem")
.jobId(63l)
.jobStatus(0)
.nics(ImmutableSet.of(NIC.builder().id(72).networkId(204).netmask("255.255.255.0").gateway("1.1.1.1")
.IPAddress("1.1.1.5").trafficType(TrafficType.GUEST).guestIPType(GuestIPType.VIRTUAL)
.isDefault(true).build())).hypervisor("XenServer").build();
NodeMetadata node = parser.apply(guest);
assertEquals(
node.toString(),
new NodeMetadataBuilder().id("54").providerId("54").name("i-3-54-VM").group("i-3")
.location(ZoneToLocationTest.one).state(NodeState.PENDING).hostname("i-3-54-VM")
.privateAddresses(ImmutableSet.<String>of())
.publicAddresses(ImmutableSet.<String>of("1.1.1.5"))
.hardware(addHypervisor(ServiceOfferingToHardwareTest.one, "XenServer"))
.imageId(TemplateToImageTest.one.getId())
.operatingSystem(TemplateToImageTest.one.getOperatingSystem()).build().toString());
}
@Test @Test
public void testApplyWhereVirtualMachineWithNoPassword() throws UnknownHostException { public void testApplyWhereVirtualMachineWithNoPassword() throws UnknownHostException {
Supplier<Set<? extends Location>> locationSupplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet Supplier<Set<? extends Location>> locationSupplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(ZoneToLocationTest.one, ZoneToLocationTest.two)); .<Location>of(ZoneToLocationTest.one, ZoneToLocationTest.two));
Supplier<Set<? extends Hardware>> hardwareSupplier = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(ServiceOfferingToHardwareTest.one, ServiceOfferingToHardwareTest.two));
Supplier<Set<? extends Image>> imageSupplier = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet Supplier<Set<? extends Image>> imageSupplier = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet
.<Image> of(TemplateToImageTest.one, TemplateToImageTest.two)); .<Image>of(TemplateToImageTest.one, TemplateToImageTest.two));
VirtualMachineToNodeMetadata parser = new VirtualMachineToNodeMetadata(new FindLocationForVirtualMachine( VirtualMachineToNodeMetadata parser = new VirtualMachineToNodeMetadata(new FindLocationForVirtualMachine(
locationSupplier), new FindHardwareForVirtualMachine(hardwareSupplier), new FindImageForVirtualMachine( locationSupplier), new FindImageForVirtualMachine(
imageSupplier), CacheBuilder.newBuilder().<Long, Set<IPForwardingRule>> build( imageSupplier), CacheBuilder.newBuilder().<Long, Set<IPForwardingRule>> build(
new CacheLoader<Long, Set<IPForwardingRule>>() { new CacheLoader<Long, Set<IPForwardingRule>>() {
@ -121,9 +182,14 @@ public class VirtualMachineToNodeMetadataTest {
node.toString(), node.toString(),
new NodeMetadataBuilder().id("54").providerId("54").name("i-3-54-VM").group("i-3") new NodeMetadataBuilder().id("54").providerId("54").name("i-3-54-VM").group("i-3")
.location(ZoneToLocationTest.one).state(NodeState.PENDING).hostname("i-3-54-VM") .location(ZoneToLocationTest.one).state(NodeState.PENDING).hostname("i-3-54-VM")
.privateAddresses(ImmutableSet.of("10.1.1.18")).hardware(ServiceOfferingToHardwareTest.one) .privateAddresses(ImmutableSet.of("10.1.1.18"))
.hardware(addHypervisor(ServiceOfferingToHardwareTest.one, "XenServer"))
.imageId(TemplateToImageTest.one.getId()) .imageId(TemplateToImageTest.one.getId())
.operatingSystem(TemplateToImageTest.one.getOperatingSystem()).build().toString()); .operatingSystem(TemplateToImageTest.one.getOperatingSystem()).build().toString());
} }
protected Hardware addHypervisor(Hardware in, String hypervisor) {
return HardwareBuilder.fromHardware(in).hypervisor(hypervisor).build();
}
} }

View File

@ -18,8 +18,10 @@
*/ */
package org.jclouds.cloudstack.features; package org.jclouds.cloudstack.features;
import java.util.Properties; import com.google.common.base.Function;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
import org.jclouds.cloudstack.CloudStackContext; import org.jclouds.cloudstack.CloudStackContext;
import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
@ -27,9 +29,11 @@ import org.jclouds.http.HttpResponse;
import org.jclouds.logging.config.NullLoggingModule; import org.jclouds.logging.config.NullLoggingModule;
import org.jclouds.rest.BaseRestClientExpectTest; import org.jclouds.rest.BaseRestClientExpectTest;
import com.google.common.base.Function; import java.net.URI;
import com.google.common.collect.ImmutableSet; import java.net.URLEncoder;
import com.google.inject.Module; import java.util.Properties;
import static org.jclouds.crypto.CryptoStreams.md5Hex;
/** /**
* Base class for writing CloudStack Rest Client Expect tests * Base class for writing CloudStack Rest Client Expect tests
@ -51,4 +55,37 @@ public abstract class BaseCloudStackRestClientExpectTest<S> extends BaseRestClie
protected abstract S clientFrom(CloudStackContext context); 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="))
.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

@ -20,6 +20,7 @@ package org.jclouds.cloudstack.features;
import org.jclouds.cloudstack.CloudStackGlobalClient; import org.jclouds.cloudstack.CloudStackGlobalClient;
import org.jclouds.cloudstack.domain.Account; import org.jclouds.cloudstack.domain.Account;
import org.jclouds.crypto.CryptoStreams;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
@ -36,7 +37,7 @@ public class GlobalAccountClientLiveTest extends BaseCloudStackClientLiveTest {
public static Account createTestAccount(CloudStackGlobalClient client, String prefix) { public static Account createTestAccount(CloudStackGlobalClient client, String prefix) {
return client.getAccountClient().createAccount( return client.getAccountClient().createAccount(
prefix + "-account", Account.Type.USER, "dummy@example.com", prefix + "-account", Account.Type.USER, "dummy@example.com",
"First", "Last", "hashed-password"); "First", "Last", CryptoStreams.md5Hex("password"));
} }
@Test @Test

View File

@ -27,6 +27,7 @@ import org.jclouds.cloudstack.domain.ApiKeyPair;
import org.jclouds.cloudstack.domain.User; import org.jclouds.cloudstack.domain.User;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.crypto.CryptoStreams;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.sshj.config.SshjSshClientModule; import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -48,7 +49,7 @@ public class GlobalUserClientLiveTest extends BaseCloudStackClientLiveTest {
public static User createTestUser(CloudStackGlobalClient client, Account account, String prefix) { public static User createTestUser(CloudStackGlobalClient client, Account account, String prefix) {
return client.getUserClient().createUser(prefix + "-user", return client.getUserClient().createUser(prefix + "-user",
account.getName(), "dummy2@example.com", "md5-password", "First", "Last"); account.getName(), "dummy2@example.com", CryptoStreams.md5Hex("password"), "First", "Last");
} }
@Test @Test

View File

@ -0,0 +1,184 @@
/**
* 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.features;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import org.jclouds.cloudstack.CloudStackContext;
import org.jclouds.cloudstack.domain.VlanIPRange;
import org.jclouds.cloudstack.options.CreateVlanIPRangeOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
import java.net.URI;
import static junit.framework.Assert.assertEquals;
/**
* Test the CloudStack VlanClient
*
* @author Richard Downer
*/
@Test(groups = "unit", testName = "GlobalVlanClientExpectTest")
public class GlobalVlanClientExpectTest extends BaseCloudStackRestClientExpectTest<GlobalVlanClient> {
public void testListVlanIpRangesWhenResponseIs2xx() {
GlobalVlanClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&" +
"command=listVlanIpRanges&apiKey=identity&signature=mS38BVfJjz1Y8bk0EdjJTeusJ0w%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/listvlaniprangesresponse.json"))
.build());
VlanIPRange range1 = VlanIPRange.builder()
.id(1)
.forVirtualNetwork(true)
.zoneId(1)
.vlan(127)
.account("system")
.domainId(1)
.domain("ROOT")
.gateway("10.27.27.254")
.netmask("255.255.255.0")
.startIP("10.27.27.50")
.endIP("10.27.27.100")
.networkId(200)
.build();
VlanIPRange range2 = VlanIPRange.builder()
.id(2)
.forVirtualNetwork(false)
.zoneId(2)
.vlan("untagged")
.account("system")
.domainId(1)
.domain("ROOT")
.podId(2)
.podName("Dev Pod 2")
.gateway("10.22.22.254")
.netmask("255.255.255.0")
.startIP("10.22.22.51")
.endIP("10.22.22.100")
.networkId(209)
.build();
assertEquals(client.listVlanIPRanges(), ImmutableSet.of(range1, range2));
}
public void testListVlanIpRangesWhenResponseIs404() {
GlobalVlanClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&" +
"command=listVlanIpRanges&apiKey=identity&signature=mS38BVfJjz1Y8bk0EdjJTeusJ0w%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(404)
.build());
assertEquals(client.listVlanIPRanges(), ImmutableSet.of());
}
public void testCreateVlanIpRangeWhenResponseIs2xx() {
GlobalVlanClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&" +
"command=createVlanIpRange&startip=10.22.22.51&endip=10.22.22.100&forvirtualnetwork=false&zoneid=2&vlan=untagged&account=system&domainid=1&podid=2&gateway=10.22.22.254&netmask=255.255.255.0&networkid=209&apiKey=identity&signature=XgDjPYAQNLMVCuSMGRA6QjV8mOY%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/createvlaniprangeresponse.json"))
.build());
VlanIPRange actual = client.createVlanIPRange("10.22.22.51", "10.22.22.100", new CreateVlanIPRangeOptions()
.forVirtualNetwork(false)
.zoneId(2)
.vlan("untagged")
.accountInDomain("system", 1)
.podId(2)
.gateway("10.22.22.254")
.netmask("255.255.255.0")
.networkId(209));
VlanIPRange expected = VlanIPRange.builder()
.id(2)
.forVirtualNetwork(false)
.zoneId(2)
.vlan("untagged")
.account("system")
.domainId(1)
.domain("ROOT")
.podId(2)
.podName("Dev Pod 2")
.gateway("10.22.22.254")
.netmask("255.255.255.0")
.startIP("10.22.22.51")
.endIP("10.22.22.100")
.networkId(209)
.build();
assertEquals(actual, expected);
}
public void testDeleteVlanIpRangeWhenResponseIs2xx() {
GlobalVlanClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&" +
"command=deleteVlanIpRange&id=1&apiKey=identity&signature=tTBbpdCndgHXdR397fbbJaN1RZU%3D"))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/createvlaniprangeresponse.json"))
.build());
client.deleteVlanIPRange(1);
}
@Override
protected GlobalVlanClient clientFrom(CloudStackContext context) {
return context.getGlobalContext().getApi().getVlanClient();
}
}

View File

@ -0,0 +1,100 @@
/**
* 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.features;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.NetworkOffering;
import org.jclouds.cloudstack.domain.VlanIPRange;
import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.options.CreateVlanIPRangeOptions;
import org.jclouds.cloudstack.options.ListVlanIPRangesOptions;
import org.jclouds.cloudstack.predicates.NetworkOfferingPredicates;
import org.jclouds.cloudstack.predicates.ZonePredicates;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import java.util.Set;
import static com.google.common.collect.Iterables.find;
import static org.testng.Assert.*;
/**
* Tests behavior of {@code GlobalVlanClient}
*
* @author Richard Downer
*/
@Test(groups = "live", singleThreaded = true, testName = "GlobalVlanClientLiveTest")
public class GlobalVlanClientLiveTest extends BaseCloudStackClientLiveTest {
private Network network;
private VlanIPRange range;
public void testListVlanIPRanges() throws Exception {
Set<VlanIPRange> response = globalAdminClient.getVlanClient().listVlanIPRanges();
assert null != response;
long rangeCount = response.size();
assertTrue(rangeCount >= 0);
for (VlanIPRange range : response) {
VlanIPRange newDetails = Iterables.getOnlyElement(globalAdminClient.getVlanClient().listVlanIPRanges(
ListVlanIPRangesOptions.Builder.id(range.getId())));
assertEquals(range, newDetails);
assertEquals(range, globalAdminClient.getVlanClient().getVlanIPRange(range.getId()));
assertFalse(range.getId() <= 0);
assertFalse(range.getZoneId() <= 0);
assertFalse(Strings.isNullOrEmpty(range.getVlan()));
assertFalse(Strings.isNullOrEmpty(range.getAccount()));
assertFalse(range.getDomainId() <= 0);
assertFalse(Strings.isNullOrEmpty(range.getDomain()));
assertFalse(Strings.isNullOrEmpty(range.getGateway()));
assertFalse(Strings.isNullOrEmpty(range.getNetmask()));
assertFalse(Strings.isNullOrEmpty(range.getStartIP()));
assertFalse(Strings.isNullOrEmpty(range.getEndIP()));
assertFalse(range.getNetworkId() <= 0);
}
}
public void testCreateVlanIPRange() {
Zone zone = Iterables.find(client.getZoneClient().listZones(), ZonePredicates.supportsAdvancedNetworks());
NetworkOffering offering = find(client.getOfferingClient().listNetworkOfferings(), NetworkOfferingPredicates.supportsGuestVirtualNetworks());
network = client.getNetworkClient().createNetworkInZone(zone.getId(), offering.getId(), "net-"+prefix, "jclouds test "+prefix);
range = globalAdminClient.getVlanClient().createVlanIPRange("172.19.1.1", "172.19.1.199", CreateVlanIPRangeOptions.Builder
.accountInDomain(user.getAccount(), user.getDomainId())
.forVirtualNetwork(true)
.vlan(1001)
.networkId(network.getId())
);
}
@AfterClass
public void testFixtureTearDown() {
if (range != null) {
globalAdminClient.getVlanClient().deleteVlanIPRange(range.getId());
range = null;
}
if (network != null) {
client.getNetworkClient().deleteNetwork(network.getId());
network = null;
}
}
}

View File

@ -0,0 +1,99 @@
/**
* 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.features;
import com.google.common.collect.ImmutableMultimap;
import org.jclouds.cloudstack.CloudStackContext;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import static org.jclouds.crypto.CryptoStreams.md5Hex;
import static org.testng.Assert.assertEquals;
/**
* Tests behavior of {@code SessionClient}
*
* @author Andrei Savu
*/
@Test(groups = "live", singleThreaded = true, testName = "SessionClientExpectTest")
public class SessionClientExpectTest extends BaseCloudStackRestClientExpectTest<SessionClient> {
@SuppressWarnings("deprecation")
public void testLoginWhenResponseIs2xxIncludesJSessionId() throws IOException {
String domain = "Partners/jCloud";
String user = "jcloud";
String password = "jcl0ud";
String md5password = md5Hex(password);
HttpRequest request = HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&command=login&" +
"username=" + user + "&password=" + md5password + "&domain=" + URLEncoder.encode(domain)))
.headers(
ImmutableMultimap.<String, String>builder()
.put("Accept", "application/json")
.build())
.build();
String jSessionId = "90DD65D13AEAA590ECCA312D150B9F6D";
SessionClient client = requestSendsResponse(request,
HttpResponse.builder()
.statusCode(200)
.headers(
ImmutableMultimap.<String, String>builder()
.put("Set-Cookie", "JSESSIONID=" + jSessionId + "; Path=/client")
.build())
.payload(payloadFromResource("/loginresponse.json"))
.build());
assertEquals(client.loginUserInDomainWithHashOfPassword(user, domain, md5password).toString(),
LoginResponse.builder().timeout(1800).lastName("Kiran").registered(false).username("jcloud").firstName("Vijay")
.domainId(11).accountType(Account.Type.DOMAIN_ADMIN).userId(19).sessionKey(
"uYT4/MNiglgAKiZRQkvV8QP8gn0=").jSessionId(jSessionId).accountName("jcloud").build().toString());
}
public void testLogout() throws IOException {
HttpRequest request = HttpRequest.builder()
.method("GET")
.endpoint(
URI.create("http://localhost:8080/client/api?response=json&command=logout&sessionkey=dummy-session-key"))
.build();
SessionClient client = requestSendsResponse(request,
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/logoutresponse.json"))
.build());
client.logoutUser("dummy-session-key");
}
@Override
protected SessionClient clientFrom(CloudStackContext context) {
return context.getProviderSpecificContext().getApi().getSessionClient();
}
}

View File

@ -0,0 +1,91 @@
/**
* 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.features;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.ApiKeyPair;
import org.jclouds.cloudstack.domain.LoginResponse;
import org.jclouds.cloudstack.domain.User;
import org.jclouds.cloudstack.util.ApiKeyPairs;
import org.jclouds.crypto.CryptoStreams;
import org.jclouds.rest.AuthorizationException;
import org.testng.annotations.Test;
import java.net.URI;
import static org.jclouds.cloudstack.features.GlobalAccountClientLiveTest.createTestAccount;
import static org.jclouds.cloudstack.features.GlobalUserClientLiveTest.createTestUser;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
/**
* Tests behavior of {@code SessionClient}
*
* @author Andrei Savu
*/
@Test(groups = "live", singleThreaded = true, testName = "SessionClientLiveTest")
public class SessionClientLiveTest extends BaseCloudStackClientLiveTest {
@Test
public void testCreateContextUsingUserAndPasswordAuthentication() {
assert globalAdminEnabled;
Account testAccount = null;
User testUser = null;
String prefix = this.prefix + "-session";
try {
testAccount = createTestAccount(globalAdminClient, prefix);
testUser = createTestUser(globalAdminClient, testAccount, prefix);
String expectedUsername = prefix + "-user";
assertEquals(testUser.getName(), expectedUsername);
checkLoginAsTheNewUser(expectedUsername);
ApiKeyPair expected = globalAdminClient.getUserClient().registerUserKeys(testUser.getId());
ApiKeyPair actual = ApiKeyPairs.loginToEndpointAsUsernameInDomainWithPasswordAndReturnApiKeyPair(
URI.create(endpoint), prefix + "-user", "password", "");
assertEquals(actual, expected);
} finally {
if (testUser != null)
globalAdminClient.getUserClient().deleteUser(testUser.getId());
if (testAccount != null)
globalAdminClient.getAccountClient().deleteAccount(testAccount.getId());
}
}
@Test(expectedExceptions = AuthorizationException.class)
public void testTryToGetApiKeypairWithWrongCredentials() {
ApiKeyPairs.loginToEndpointAsUsernameInDomainWithPasswordAndReturnApiKeyPair(
URI.create(endpoint), "dummy-missing-user", "with-a-wrong-password", "");
}
private void checkLoginAsTheNewUser(String expectedUsername) {
LoginResponse response = globalAdminClient.getSessionClient()
.loginUserInDomainWithHashOfPassword(expectedUsername, "", CryptoStreams.md5Hex("password"));
assertNotNull(response);
assertNotNull(response.getSessionKey());
assertNotNull(response.getJSessionId());
client.getSessionClient().logoutUser(response.getSessionKey());
}
}

View File

@ -78,6 +78,7 @@ public class TemplateClientLiveTest extends BaseCloudStackClientLiveTest {
assert template.getHypervisor() != null : template; assert template.getHypervisor() != null : template;
assert template.getDomain() != null : template; assert template.getDomain() != null : template;
assert template.getDomainId() > 0 : template; assert template.getDomainId() > 0 : template;
assert template.getSize() > 0 : template;
} }
} }

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);
}
}

View File

@ -0,0 +1,127 @@
/**
* 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.options;
import com.google.common.collect.ImmutableSet;
import org.testng.annotations.Test;
import static org.jclouds.cloudstack.options.CreateVlanIPRangeOptions.Builder.*;
import static org.testng.Assert.assertEquals;
/**
* Tests behavior of {@code CreateVlanIPRangeOptions}
*
* @author Richard Downer
*/
@Test(groups = "unit")
public class CreateVlanIPRangeOptionsTest {
public void testAccountInDomain() {
CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().accountInDomain("fred", 6);
assertEquals(ImmutableSet.of("fred"), options.buildQueryParameters().get("account"));
assertEquals(ImmutableSet.of("6"), options.buildQueryParameters().get("domainid"));
}
public void testAccountInDomainStatic() {
CreateVlanIPRangeOptions options = accountInDomain("fred", 6);
assertEquals(ImmutableSet.of("fred"), options.buildQueryParameters().get("account"));
assertEquals(ImmutableSet.of("6"), options.buildQueryParameters().get("domainid"));
}
public void testDomainId() {
CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().domainId(6);
assertEquals(ImmutableSet.of("6"), options.buildQueryParameters().get("domainid"));
}
public void testDomainIdStatic() {
CreateVlanIPRangeOptions options = domainId(6);
assertEquals(ImmutableSet.of("6"), options.buildQueryParameters().get("domainid"));
}
public void testForVirtualNetwork() {
CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().forVirtualNetwork(true);
assertEquals(ImmutableSet.of("true"), options.buildQueryParameters().get("forvirtualnetwork"));
}
public void testForVirtualNetworkStatic() {
CreateVlanIPRangeOptions options = forVirtualNetwork(true);
assertEquals(ImmutableSet.of("true"), options.buildQueryParameters().get("forvirtualnetwork"));
}
public void testGateway() {
CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().gateway("192.168.42.24");
assertEquals(ImmutableSet.of("192.168.42.24"), options.buildQueryParameters().get("gateway"));
}
public void testGatewayStatic() {
CreateVlanIPRangeOptions options = gateway("192.168.42.24");
assertEquals(ImmutableSet.of("192.168.42.24"), options.buildQueryParameters().get("gateway"));
}
public void testNetmask() {
CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().netmask("255.255.255.240");
assertEquals(ImmutableSet.of("255.255.255.240"), options.buildQueryParameters().get("netmask"));
}
public void testNetmaskStatic() {
CreateVlanIPRangeOptions options = netmask("255.255.255.240");
assertEquals(ImmutableSet.of("255.255.255.240"), options.buildQueryParameters().get("netmask"));
}
public void testNetworkId() {
CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().networkId(9);
assertEquals(ImmutableSet.of("9"), options.buildQueryParameters().get("networkid"));
}
public void testNetworkIdStatic() {
CreateVlanIPRangeOptions options = networkId(9);
assertEquals(ImmutableSet.of("9"), options.buildQueryParameters().get("networkid"));
}
public void testPodId() {
CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().podId(8);
assertEquals(ImmutableSet.of("8"), options.buildQueryParameters().get("podid"));
}
public void testPodIdStatic() {
CreateVlanIPRangeOptions options = podId(8);
assertEquals(ImmutableSet.of("8"), options.buildQueryParameters().get("podid"));
}
public void testVlan() {
CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().vlan(1001);
assertEquals(ImmutableSet.of("1001"), options.buildQueryParameters().get("vlan"));
}
public void testVlanStatic() {
CreateVlanIPRangeOptions options = vlan(1001);
assertEquals(ImmutableSet.of("1001"), options.buildQueryParameters().get("vlan"));
}
public void testZoneId() {
CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().zoneId(7);
assertEquals(ImmutableSet.of("7"), options.buildQueryParameters().get("zoneid"));
}
public void testZoneIdStatic() {
CreateVlanIPRangeOptions options = zoneId(7);
assertEquals(ImmutableSet.of("7"), options.buildQueryParameters().get("zoneid"));
}
}

View File

@ -0,0 +1,127 @@
/**
* 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.options;
import com.google.common.collect.ImmutableList;
import org.testng.annotations.Test;
import static org.jclouds.cloudstack.options.ListVlanIPRangesOptions.Builder.*;
import static org.testng.Assert.assertEquals;
/**
* Tests behavior of {@code ListVlanIPRangesOptions}
*
* @author Richard Downer
*/
@Test(groups = "unit")
public class ListVlanIPRangesOptionsTest {
public void testAccountInDomain() {
ListVlanIPRangesOptions options = new ListVlanIPRangesOptions().accountInDomain("fred", 19);
assertEquals(ImmutableList.of("fred"), options.buildQueryParameters().get("account"));
assertEquals(ImmutableList.of("19"), options.buildQueryParameters().get("domainid"));
}
public void testAccountInDomainStatic() {
ListVlanIPRangesOptions options = accountInDomain("fred", 19);
assertEquals(ImmutableList.of("fred"), options.buildQueryParameters().get("account"));
assertEquals(ImmutableList.of("19"), options.buildQueryParameters().get("domainid"));
}
public void testDomainId() {
ListVlanIPRangesOptions options = new ListVlanIPRangesOptions().domainId(19);
assertEquals(ImmutableList.of("19"), options.buildQueryParameters().get("domainid"));
}
public void testDomainIdStatic() {
ListVlanIPRangesOptions options = domainId(19);
assertEquals(ImmutableList.of("19"), options.buildQueryParameters().get("domainid"));
}
public void testForVirtualNetwork() {
ListVlanIPRangesOptions options = new ListVlanIPRangesOptions().forVirtualNetwork(true);
assertEquals(ImmutableList.of("true"), options.buildQueryParameters().get("forvirtualnetwork"));
}
public void testForVirtualNetworkStatic() {
ListVlanIPRangesOptions options = forVirtualNetwork(true);
assertEquals(ImmutableList.of("true"), options.buildQueryParameters().get("forvirtualnetwork"));
}
public void testId() {
ListVlanIPRangesOptions options = new ListVlanIPRangesOptions().id(6);
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("id"));
}
public void testIdStatic() {
ListVlanIPRangesOptions options = id(6);
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("id"));
}
public void testKeyword() {
ListVlanIPRangesOptions options = new ListVlanIPRangesOptions().keyword("fred");
assertEquals(ImmutableList.of("fred"), options.buildQueryParameters().get("keyword"));
}
public void testKeywordStatic() {
ListVlanIPRangesOptions options = keyword("fred");
assertEquals(ImmutableList.of("fred"), options.buildQueryParameters().get("keyword"));
}
public void testNetworkId() {
ListVlanIPRangesOptions options = new ListVlanIPRangesOptions().networkId(209);
assertEquals(ImmutableList.of("209"), options.buildQueryParameters().get("networkid"));
}
public void testNetworkIdStatic() {
ListVlanIPRangesOptions options = networkId(209);
assertEquals(ImmutableList.of("209"), options.buildQueryParameters().get("networkid"));
}
public void testPodId() {
ListVlanIPRangesOptions options = new ListVlanIPRangesOptions().podId(13);
assertEquals(ImmutableList.of("13"), options.buildQueryParameters().get("podid"));
}
public void testPodIdStatic() {
ListVlanIPRangesOptions options = podId(13);
assertEquals(ImmutableList.of("13"), options.buildQueryParameters().get("podid"));
}
public void testVlan() {
ListVlanIPRangesOptions options = new ListVlanIPRangesOptions().vlan(1001);
assertEquals(ImmutableList.of("1001"), options.buildQueryParameters().get("vlan"));
}
public void testVlanStatic() {
ListVlanIPRangesOptions options = vlan(1001);
assertEquals(ImmutableList.of("1001"), options.buildQueryParameters().get("vlan"));
}
public void testZoneId() {
ListVlanIPRangesOptions options = new ListVlanIPRangesOptions().zoneId(6);
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("zoneid"));
}
public void testZoneIdStatic() {
ListVlanIPRangesOptions options = zoneId(6);
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("zoneid"));
}
}

View File

@ -0,0 +1,76 @@
/**
* 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.parse;
import com.google.common.collect.ImmutableSet;
import org.jclouds.cloudstack.domain.VlanIPRange;
import org.jclouds.json.BaseSetParserTest;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import java.util.Set;
/**
*
* @author Richard Downer
*/
@Test(groups = "unit")
public class ListVlanIPRangesResponseTest extends BaseSetParserTest<VlanIPRange> {
@Override
public String resource() {
return "/listvlaniprangesresponse.json";
}
@Override
@SelectJson("vlaniprange")
public Set<VlanIPRange> expected() {
VlanIPRange range1 = VlanIPRange.builder()
.id(1)
.forVirtualNetwork(true)
.zoneId(1)
.vlan(127)
.account("system")
.domainId(1)
.domain("ROOT")
.gateway("10.27.27.254")
.netmask("255.255.255.0")
.startIP("10.27.27.50")
.endIP("10.27.27.100")
.networkId(200)
.build();
VlanIPRange range2 = VlanIPRange.builder()
.id(2)
.forVirtualNetwork(false)
.zoneId(2)
.vlan("untagged")
.account("system")
.domainId(1)
.domain("ROOT")
.podId(2)
.podName("Dev Pod 2")
.gateway("10.22.22.254")
.netmask("255.255.255.0")
.startIP("10.22.22.51")
.endIP("10.22.22.100")
.networkId(209)
.build();
return ImmutableSet.of(range1, range2);
}
}

View File

@ -0,0 +1 @@
{ "createvlaniprangeresponse" : { "vlaniprange" : {"id":2,"forvirtualnetwork":false,"zoneid":2,"vlan":"untagged","account":"system","domainid":1,"domain":"ROOT","podid":2,"podname":"Dev Pod 2","gateway":"10.22.22.254","netmask":"255.255.255.0","startip":"10.22.22.51","endip":"10.22.22.100","networkid":209} } }

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