mirror of
https://github.com/apache/jclouds.git
synced 2025-02-17 15:35:44 +00:00
Issue 100: started support, adding upload functionality for nirvanix sdn
git-svn-id: http://jclouds.googlecode.com/svn/trunk@1953 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
5b7878b0ea
commit
ccd035df64
@ -29,9 +29,9 @@ import javax.ws.rs.QueryParam;
|
|||||||
|
|
||||||
import org.jclouds.nirvanix.sdn.functions.ParseSessionTokenFromJsonResponse;
|
import org.jclouds.nirvanix.sdn.functions.ParseSessionTokenFromJsonResponse;
|
||||||
import org.jclouds.nirvanix.sdn.reference.SDNQueryParams;
|
import org.jclouds.nirvanix.sdn.reference.SDNQueryParams;
|
||||||
import org.jclouds.rest.Endpoint;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.QueryParams;
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
import org.jclouds.rest.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to Nirvanix SDN resources via their REST API.
|
* Provides access to Nirvanix SDN resources via their REST API.
|
||||||
@ -45,7 +45,7 @@ import org.jclouds.rest.ResponseParser;
|
|||||||
public interface SDNAuthentication {
|
public interface SDNAuthentication {
|
||||||
|
|
||||||
public interface AuthenticationResponse {
|
public interface AuthenticationResponse {
|
||||||
@Authentication
|
@SessionToken
|
||||||
String getSessionToken();
|
String getSessionToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.nirvanix.sdn;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.decorators.AddBlobEntityAsMultipartForm;
|
||||||
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
|
import org.jclouds.nirvanix.sdn.decorators.AddMetadataAsQueryParams;
|
||||||
|
import org.jclouds.nirvanix.sdn.domain.UploadInfo;
|
||||||
|
import org.jclouds.nirvanix.sdn.filters.AddSessionTokenToRequest;
|
||||||
|
import org.jclouds.nirvanix.sdn.functions.ParseUploadInfoFromJsonResponse;
|
||||||
|
import org.jclouds.nirvanix.sdn.reference.SDNQueryParams;
|
||||||
|
import org.jclouds.rest.annotations.DecoratorParam;
|
||||||
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to Nirvanix SDN resources via their REST API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @see <a href="http://developer.nirvanix.com/sitefiles/1000/API.html" />
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Endpoint(SDN.class)
|
||||||
|
@QueryParams(keys = SDNQueryParams.OUTPUT, values = "json")
|
||||||
|
@RequestFilters(AddSessionTokenToRequest.class)
|
||||||
|
@SkipEncoding( { '/', ':' })
|
||||||
|
public interface SDNConnection {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The GetStorageNode method is used to determine which storage node a file should be uploaded
|
||||||
|
* to. It returns the host to upload to and an Upload Token that will be used to authenticate.
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/IMFS/GetStorageNode.ashx")
|
||||||
|
@ResponseParser(ParseUploadInfoFromJsonResponse.class)
|
||||||
|
UploadInfo getStorageNode(@QueryParam(SDNQueryParams.DESTFOLDERPATH) String folderPath,
|
||||||
|
@QueryParam(SDNQueryParams.SIZEBYTES) long size);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/Upload.ashx")
|
||||||
|
Future<Void> upload(@Endpoint URI endpoint,
|
||||||
|
@QueryParam(SDNQueryParams.UPLOADTOKEN) String uploadToken,
|
||||||
|
@QueryParam(SDNQueryParams.DESTFOLDERPATH) String folderPath,
|
||||||
|
@DecoratorParam(AddBlobEntityAsMultipartForm.class) Blob<BlobMetadata> blob);
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/Metadata/SetMetadata.ashx")
|
||||||
|
@QueryParams(keys = SDNQueryParams.PATH, values = "{container}/{key}")
|
||||||
|
Future<Void> setMetadata(@PathParam("container") String container, @PathParam("key") String key,
|
||||||
|
@DecoratorParam(AddMetadataAsQueryParams.class) Multimap<String, String> metadata);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package org.jclouds.nirvanix.sdn;
|
||||||
|
|
||||||
|
import org.jclouds.cloud.CloudContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an authenticated context to Nirvanix SDN.
|
||||||
|
*
|
||||||
|
* @see <a href="http://developer.nirvanix.com/sitefiles/1000/API.html" />
|
||||||
|
* @see SDNConnection
|
||||||
|
* @see CloudContext
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface SDNContext extends CloudContext<SDNConnection> {
|
||||||
|
|
||||||
|
}
|
@ -28,11 +28,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import org.jclouds.cloud.CloudContextBuilder;
|
import org.jclouds.cloud.CloudContextBuilder;
|
||||||
import org.jclouds.nirvanix.sdn.config.RestSDNAuthenticationModule;
|
import org.jclouds.nirvanix.sdn.config.RestSDNAuthenticationModule;
|
||||||
|
import org.jclouds.nirvanix.sdn.config.SDNContextModule;
|
||||||
import org.jclouds.nirvanix.sdn.reference.SDNConstants;
|
import org.jclouds.nirvanix.sdn.reference.SDNConstants;
|
||||||
|
|
||||||
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
@ -40,15 +43,16 @@ import com.google.inject.TypeLiteral;
|
|||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public abstract class SDNContextBuilder<C> extends CloudContextBuilder<C> {
|
public class SDNContextBuilder extends CloudContextBuilder<SDNConnection> {
|
||||||
|
|
||||||
public SDNContextBuilder(TypeLiteral<C> defaultApiClass, String apikey, String id, String secret) {
|
public SDNContextBuilder(String apikey, String id, String secret) {
|
||||||
this(defaultApiClass, new Properties());
|
this(new Properties());
|
||||||
authenticate(this, apikey, id, secret);
|
authenticate(this, apikey, id, secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SDNContextBuilder(TypeLiteral<C> defaultApiClass, Properties props) {
|
public SDNContextBuilder(Properties props) {
|
||||||
super(defaultApiClass, props);
|
super(new TypeLiteral<SDNConnection>() {
|
||||||
|
}, props);
|
||||||
initialize(this);
|
initialize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,31 +61,109 @@ public abstract class SDNContextBuilder<C> extends CloudContextBuilder<C> {
|
|||||||
addAuthenticationModule(this);
|
addAuthenticationModule(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <C> void authenticate(CloudContextBuilder<C> builder, String appkey, String id,
|
public static void authenticate(SDNContextBuilder builder, String appkey, String id,
|
||||||
String secret) {
|
String secret) {
|
||||||
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_APPKEY, checkNotNull(appkey, "appkey"));
|
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_APPKEY,
|
||||||
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_USERNAME, checkNotNull(id, "user"));
|
checkNotNull(appkey, "appkey"));
|
||||||
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_PASSWORD, checkNotNull(secret, "key"));
|
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_USERNAME,
|
||||||
|
checkNotNull(id, "user"));
|
||||||
|
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_PASSWORD,
|
||||||
|
checkNotNull(secret, "key"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <C> void initialize(CloudContextBuilder<C> builder) {
|
public static void initialize(SDNContextBuilder builder) {
|
||||||
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_ENDPOINT, "http://services.nirvanix.com/ws");
|
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_ENDPOINT,
|
||||||
|
"http://services.nirvanix.com/ws");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <C> void addAuthenticationModule(CloudContextBuilder<C> builder) {
|
public static void addAuthenticationModule(SDNContextBuilder builder) {
|
||||||
builder.withModule(new RestSDNAuthenticationModule());
|
builder.withModule(new RestSDNAuthenticationModule());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <C> CloudContextBuilder<C> withEndpoint(CloudContextBuilder<C> builder,
|
public static SDNContextBuilder withEndpoint(SDNContextBuilder builder, URI endpoint) {
|
||||||
URI endpoint) {
|
|
||||||
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_ENDPOINT,
|
builder.getProperties().setProperty(SDNConstants.PROPERTY_SDN_ENDPOINT,
|
||||||
checkNotNull(endpoint, "endpoint").toString());
|
checkNotNull(endpoint, "endpoint").toString());
|
||||||
return builder;
|
return (SDNContextBuilder) builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SDNContextBuilder<C> withEndpoint(URI endpoint) {
|
public SDNContextBuilder relaxSSLHostname() {
|
||||||
return (SDNContextBuilder<C>) withEndpoint(this, endpoint);
|
return (SDNContextBuilder) super.relaxSSLHostname();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withExecutorService(ExecutorService service) {
|
||||||
|
return (SDNContextBuilder) super.withExecutorService(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withHttpMaxRedirects(int httpMaxRedirects) {
|
||||||
|
return (SDNContextBuilder) super.withHttpMaxRedirects(httpMaxRedirects);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withHttpMaxRetries(int httpMaxRetries) {
|
||||||
|
return (SDNContextBuilder) super.withHttpMaxRetries(httpMaxRetries);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withJsonDebug() {
|
||||||
|
return (SDNContextBuilder) super.withJsonDebug();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withModule(Module module) {
|
||||||
|
return (SDNContextBuilder) super.withModule(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withModules(Module... modules) {
|
||||||
|
return (SDNContextBuilder) super.withModules(modules);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withPoolIoWorkerThreads(int poolIoWorkerThreads) {
|
||||||
|
return (SDNContextBuilder) super.withPoolIoWorkerThreads(poolIoWorkerThreads);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withPoolMaxConnectionReuse(int poolMaxConnectionReuse) {
|
||||||
|
return (SDNContextBuilder) super.withPoolMaxConnectionReuse(poolMaxConnectionReuse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withPoolMaxConnections(int poolMaxConnections) {
|
||||||
|
return (SDNContextBuilder) super.withPoolMaxConnections(poolMaxConnections);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withPoolMaxSessionFailures(int poolMaxSessionFailures) {
|
||||||
|
return (SDNContextBuilder) super.withPoolMaxSessionFailures(poolMaxSessionFailures);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withPoolRequestInvokerThreads(int poolRequestInvokerThreads) {
|
||||||
|
return (SDNContextBuilder) super.withPoolRequestInvokerThreads(poolRequestInvokerThreads);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withSaxDebug() {
|
||||||
|
return (SDNContextBuilder) super.withSaxDebug();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContextBuilder withEndpoint(URI endpoint) {
|
||||||
|
return (SDNContextBuilder) (SDNContextBuilder) withEndpoint(this, endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addContextModule(List<Module> modules) {
|
||||||
|
modules.add(new SDNContextModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SDNContext buildContext() {
|
||||||
|
Injector injector = buildInjector();
|
||||||
|
return injector.getInstance(SDNContext.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,6 @@ import javax.inject.Qualifier;
|
|||||||
@Retention(value = RetentionPolicy.RUNTIME)
|
@Retention(value = RetentionPolicy.RUNTIME)
|
||||||
@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||||
@Qualifier
|
@Qualifier
|
||||||
public @interface Authentication {
|
public @interface SessionToken {
|
||||||
|
|
||||||
}
|
}
|
@ -29,11 +29,12 @@ import javax.inject.Named;
|
|||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.http.RequiresHttp;
|
import org.jclouds.http.RequiresHttp;
|
||||||
import org.jclouds.nirvanix.sdn.Authentication;
|
import org.jclouds.nirvanix.sdn.SDN;
|
||||||
import org.jclouds.nirvanix.sdn.SDNAuthentication;
|
import org.jclouds.nirvanix.sdn.SDNAuthentication;
|
||||||
|
import org.jclouds.nirvanix.sdn.SDNConnection;
|
||||||
|
import org.jclouds.nirvanix.sdn.SessionToken;
|
||||||
import org.jclouds.nirvanix.sdn.reference.SDNConstants;
|
import org.jclouds.nirvanix.sdn.reference.SDNConstants;
|
||||||
import org.jclouds.rest.RestClientFactory;
|
import org.jclouds.rest.RestClientFactory;
|
||||||
import org.jclouds.rest.config.JaxrsModule;
|
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
@ -48,20 +49,19 @@ public class RestSDNAuthenticationModule extends AbstractModule {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
install(new JaxrsModule());
|
|
||||||
bindErrorHandlers();
|
bindErrorHandlers();
|
||||||
bindRetryHandlers();
|
bindRetryHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@Authentication
|
@SDN
|
||||||
protected URI provideAuthenticationURI(@Named(SDNConstants.PROPERTY_SDN_ENDPOINT) String endpoint) {
|
protected URI provideAuthenticationURI(@Named(SDNConstants.PROPERTY_SDN_ENDPOINT) String endpoint) {
|
||||||
return URI.create(endpoint);
|
return URI.create(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Authentication
|
@SessionToken
|
||||||
protected String provideSessionToken(RestClientFactory factory,
|
protected String provideSessionToken(RestClientFactory factory,
|
||||||
@Named(SDNConstants.PROPERTY_SDN_APPKEY) String appKey,
|
@Named(SDNConstants.PROPERTY_SDN_APPKEY) String appKey,
|
||||||
@Named(SDNConstants.PROPERTY_SDN_USERNAME) String username,
|
@Named(SDNConstants.PROPERTY_SDN_USERNAME) String username,
|
||||||
@ -69,6 +69,11 @@ public class RestSDNAuthenticationModule extends AbstractModule {
|
|||||||
return factory.create(SDNAuthentication.class).authenticate(appKey, username, password);
|
return factory.create(SDNAuthentication.class).authenticate(appKey, username, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
protected SDNConnection provideConnection(RestClientFactory factory) {
|
||||||
|
return factory.create(SDNConnection.class);
|
||||||
|
}
|
||||||
|
|
||||||
protected void bindErrorHandlers() {
|
protected void bindErrorHandlers() {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
package org.jclouds.nirvanix.sdn.config;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
import org.jclouds.cloud.internal.CloudContextImpl;
|
||||||
|
import org.jclouds.http.RequiresHttp;
|
||||||
|
import org.jclouds.lifecycle.Closer;
|
||||||
|
import org.jclouds.nirvanix.sdn.SDN;
|
||||||
|
import org.jclouds.nirvanix.sdn.SDNConnection;
|
||||||
|
import org.jclouds.nirvanix.sdn.SDNContext;
|
||||||
|
import org.jclouds.nirvanix.sdn.reference.SDNConstants;
|
||||||
|
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Scopes;
|
||||||
|
|
||||||
|
@RequiresHttp
|
||||||
|
public class SDNContextModule extends AbstractModule {
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(SDNContext.class).to(SDNContextImpl.class).in(Scopes.SINGLETON);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SDNContextImpl extends CloudContextImpl<SDNConnection> implements SDNContext {
|
||||||
|
@Inject
|
||||||
|
public SDNContextImpl(Closer closer, SDNConnection defaultApi, @SDN URI endPoint,
|
||||||
|
@Named(SDNConstants.PROPERTY_SDN_USERNAME) String account) {
|
||||||
|
super(closer, defaultApi, endPoint, account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package org.jclouds.nirvanix.sdn.decorators;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpRequestFilter;
|
||||||
|
import org.jclouds.rest.decorators.RequestDecorator;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
public class AddMetadataAsQueryParams implements RequestDecorator {
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public HttpRequest decorateRequest(HttpRequest request, Object input) {
|
||||||
|
checkArgument(checkNotNull(input, "input") instanceof Multimap,
|
||||||
|
"this decorator is only valid for Multimaps!");
|
||||||
|
|
||||||
|
UriBuilder builder = UriBuilder.fromUri(request.getEndpoint());
|
||||||
|
Multimap<String, String> userMetadata = (Multimap<String, String>) input;
|
||||||
|
List<String> metadata = Lists.newArrayList();
|
||||||
|
for (Entry<String, String> entry : userMetadata.entries()) {
|
||||||
|
metadata.add(String.format("%s:%s", entry.getKey().toLowerCase(), entry.getValue()));
|
||||||
|
}
|
||||||
|
builder.replaceQueryParam("metadata", metadata.toArray());
|
||||||
|
List<HttpRequestFilter> oldFilters = request.getFilters();
|
||||||
|
request = new HttpRequest(request.getMethod(), builder.build(), request.getHeaders(), request
|
||||||
|
.getEntity());
|
||||||
|
request.getFilters().addAll(oldFilters);
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package org.jclouds.nirvanix.sdn.domain;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
public class UploadInfo {
|
||||||
|
private final String token;
|
||||||
|
private final URI host;
|
||||||
|
|
||||||
|
public UploadInfo(String token, URI host) {
|
||||||
|
this.token = token;
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public URI getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package org.jclouds.nirvanix.sdn.filters;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Provider;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpException;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpRequestFilter;
|
||||||
|
import org.jclouds.nirvanix.sdn.SessionToken;
|
||||||
|
import org.jclouds.nirvanix.sdn.reference.SDNQueryParams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the Session Token to the request. This will update the Session Token before 20 minutes is
|
||||||
|
* up.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class AddSessionTokenToRequest implements HttpRequestFilter {
|
||||||
|
|
||||||
|
private final Provider<String> authTokenProvider;
|
||||||
|
|
||||||
|
public final long BILLION = 1000000000;
|
||||||
|
public final long MINUTES = 60 * BILLION;
|
||||||
|
|
||||||
|
private final AtomicReference<String> authToken;
|
||||||
|
private final AtomicLong trigger = new AtomicLong(0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the time update service. Nirvanix clocks need to be 20 minutes of the session token.
|
||||||
|
* This is not performed per-request, as creation of the token is a slow, synchronized command.
|
||||||
|
*/
|
||||||
|
synchronized void updateIfTimeOut() {
|
||||||
|
|
||||||
|
if (trigger.get() - System.nanoTime() <= 0) {
|
||||||
|
createNewToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is a hotspot when submitted concurrently, so be lazy.
|
||||||
|
// session tokens expire in 20 minutes of no use, but let's be a little paraniod and go 19
|
||||||
|
public String createNewToken() {
|
||||||
|
authToken.set(authTokenProvider.get());
|
||||||
|
trigger.set(System.nanoTime() + System.nanoTime() + 19 * MINUTES);
|
||||||
|
return authToken.get();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionToken() {
|
||||||
|
updateIfTimeOut();
|
||||||
|
return authToken.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public AddSessionTokenToRequest(@SessionToken Provider<String> authTokenProvider) {
|
||||||
|
this.authTokenProvider = authTokenProvider;
|
||||||
|
authToken = new AtomicReference<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpRequest filter(HttpRequest request) throws HttpException {
|
||||||
|
UriBuilder builder = UriBuilder.fromUri(request.getEndpoint());
|
||||||
|
builder.replaceQueryParam(SDNQueryParams.SESSIONTOKEN, getSessionToken());
|
||||||
|
List<HttpRequestFilter> oldFilters = request.getFilters();
|
||||||
|
request = new HttpRequest(request.getMethod(), builder.build(), request.getHeaders(), request
|
||||||
|
.getEntity());
|
||||||
|
request.getFilters().addAll(oldFilters);
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.nirvanix.sdn.functions;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.ParseJson;
|
||||||
|
import org.jclouds.nirvanix.sdn.domain.UploadInfo;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This parses the Nirvanix Upload host and token from a gson string.
|
||||||
|
*
|
||||||
|
* @see UploadInfo
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class ParseUploadInfoFromJsonResponse extends ParseJson<UploadInfo> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ParseUploadInfoFromJsonResponse(Gson gson) {
|
||||||
|
super(gson);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class StorageNodeResponse {
|
||||||
|
Integer ResponseCode;
|
||||||
|
Map<String, String> GetStorageNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UploadInfo apply(InputStream stream) {
|
||||||
|
try {
|
||||||
|
StorageNodeResponse response = gson.fromJson(new InputStreamReader(stream, "UTF-8"),
|
||||||
|
StorageNodeResponse.class);
|
||||||
|
if (response.ResponseCode == null || response.ResponseCode != 0)
|
||||||
|
throw new RuntimeException("bad response code: " + response.ResponseCode);
|
||||||
|
return new UploadInfo(response.GetStorageNode.get("UploadToken"),
|
||||||
|
URI.create("https://" + response.GetStorageNode.get("UploadHost")));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException("jclouds requires UTF-8 encoding", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -35,4 +35,9 @@ public interface SDNQueryParams {
|
|||||||
public static final String PASSWORD = "password";
|
public static final String PASSWORD = "password";
|
||||||
public static final String APPKEY = "appKey";
|
public static final String APPKEY = "appKey";
|
||||||
public static final String OUTPUT = "output";
|
public static final String OUTPUT = "output";
|
||||||
|
public static final String SESSIONTOKEN = "sessionToken";
|
||||||
|
public static final String DESTFOLDERPATH = "destFolderPath";
|
||||||
|
public static final String PATH = "path";
|
||||||
|
public static final String SIZEBYTES = "sizeBytes";
|
||||||
|
public static final String UPLOADTOKEN = "uploadToken";
|
||||||
}
|
}
|
@ -36,7 +36,7 @@ import org.jclouds.concurrent.config.ExecutorServiceModule;
|
|||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.rest.RestClientFactory;
|
import org.jclouds.rest.RestClientFactory;
|
||||||
import org.jclouds.rest.config.JaxrsModule;
|
import org.jclouds.rest.config.RestModule;
|
||||||
import org.jclouds.util.Jsr330;
|
import org.jclouds.util.Jsr330;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
@ -82,7 +82,7 @@ public class SDNAuthenticationLiveTest {
|
|||||||
protected SDNAuthentication provideCloud(RestClientFactory factory) {
|
protected SDNAuthentication provideCloud(RestClientFactory factory) {
|
||||||
return factory.create(SDNAuthentication.class);
|
return factory.create(SDNAuthentication.class);
|
||||||
}
|
}
|
||||||
}, new JaxrsModule(), new Log4JLoggingModule(), new ExecutorServiceModule(
|
}, new RestModule(), new Log4JLoggingModule(), new ExecutorServiceModule(
|
||||||
new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule());
|
new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.nirvanix.sdn;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.ws.rs.HttpMethod;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||||
|
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
|
import org.jclouds.nirvanix.sdn.functions.ParseSessionTokenFromJsonResponse;
|
||||||
|
import org.jclouds.rest.config.RestModule;
|
||||||
|
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Key;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code JaxrsAnnotationProcessor}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "sdn.SDNAuthentication")
|
||||||
|
public class SDNAuthenticationTest {
|
||||||
|
|
||||||
|
private RestAnnotationProcessor<SDNAuthentication> processor;
|
||||||
|
|
||||||
|
public void testAuthenticate() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SDNAuthentication.class.getMethod("authenticate", String.class, String.class,
|
||||||
|
String.class);
|
||||||
|
HttpRequest httpMethod = processor.createRequest(method,
|
||||||
|
new Object[] { "apple", "foo", "bar" });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/Authentication/Login.ashx");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getQuery(),
|
||||||
|
"output=json&password=bar&username=foo&appKey=apple");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
|
assertEquals(RestAnnotationProcessor.getParserOrThrowException(method),
|
||||||
|
ParseSessionTokenFromJsonResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
void setupFactory() {
|
||||||
|
Injector injector = Guice.createInjector(new AbstractModule() {
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(URI.class).annotatedWith(SDN.class)
|
||||||
|
.toInstance(URI.create("http://localhost:8080"));
|
||||||
|
}
|
||||||
|
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||||
|
new JavaUrlHttpCommandExecutorServiceModule());
|
||||||
|
processor = injector.getInstance(Key
|
||||||
|
.get(new TypeLiteral<RestAnnotationProcessor<SDNAuthentication>>() {
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package org.jclouds.nirvanix.sdn;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
|
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
||||||
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
|
import org.jclouds.nirvanix.sdn.domain.UploadInfo;
|
||||||
|
import org.testng.annotations.BeforeGroups;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code SDNConnection}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", sequential = true, testName = "sdn.SDNConnectionLiveTest")
|
||||||
|
public class SDNConnectionLiveTest {
|
||||||
|
|
||||||
|
protected SDNConnection connection;
|
||||||
|
private String containerPrefix = BaseBlobStoreIntegrationTest.CONTAINER_PREFIX;
|
||||||
|
|
||||||
|
URI container1;
|
||||||
|
URI container2;
|
||||||
|
|
||||||
|
@BeforeGroups(groups = { "live" })
|
||||||
|
public void setupConnection() {
|
||||||
|
String app = checkNotNull(System.getProperty("jclouds.test.app"), "jclouds.test.app");
|
||||||
|
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||||
|
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||||
|
|
||||||
|
connection = new SDNContextBuilder(app, user, password).withModules(new Log4JLoggingModule())
|
||||||
|
.withJsonDebug().buildContext().getApi();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUploadToken() throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
|
String containerName = containerPrefix + ".testObjectOperations";
|
||||||
|
long size = 1024;
|
||||||
|
UploadInfo uploadInfo = connection.getStorageNode(containerName, size);
|
||||||
|
assertNotNull(uploadInfo.getHost());
|
||||||
|
assertNotNull(uploadInfo.getToken());
|
||||||
|
|
||||||
|
connection.upload(uploadInfo.getHost(), uploadInfo.getToken(), "container",
|
||||||
|
new Blob<BlobMetadata>("key", "value")).get(30, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
// Multimap<String, String> metadata = ImmutableMultimap.of("chef", "sushi");
|
||||||
|
// who knows... 403 error; connection.setMetadata("container", "key", metadata).get(30, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,148 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.nirvanix.sdn;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import javax.ws.rs.HttpMethod;
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.decorators.AddBlobEntityAsMultipartFormTest;
|
||||||
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
|
import org.jclouds.concurrent.WithinThreadExecutorService;
|
||||||
|
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
|
import org.jclouds.http.functions.ReturnVoidIf2xx;
|
||||||
|
import org.jclouds.nirvanix.sdn.functions.ParseUploadInfoFromJsonResponse;
|
||||||
|
import org.jclouds.rest.config.RestModule;
|
||||||
|
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||||
|
import org.jclouds.util.Utils;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Key;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code JaxrsAnnotationProcessor}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "sdn.SDNConnection")
|
||||||
|
public class SDNConnectionTest {
|
||||||
|
|
||||||
|
private RestAnnotationProcessor<SDNConnection> processor;
|
||||||
|
|
||||||
|
public void testGetStorageNode() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SDNConnection.class.getMethod("getStorageNode", String.class, long.class);
|
||||||
|
HttpRequest httpMethod = processor.createRequest(method, new Object[] { "adriansmovies",
|
||||||
|
734859264 });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/IMFS/GetStorageNode.ashx");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getQuery(),
|
||||||
|
"output=json&sizeBytes=734859264&destFolderPath=adriansmovies");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
|
assertEquals(RestAnnotationProcessor.getParserOrThrowException(method),
|
||||||
|
ParseUploadInfoFromJsonResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUpload() throws SecurityException, NoSuchMethodException, IOException {
|
||||||
|
Method method = SDNConnection.class.getMethod("upload", URI.class, String.class,
|
||||||
|
String.class, Blob.class);
|
||||||
|
Blob<BlobMetadata> blob = AddBlobEntityAsMultipartFormTest.TEST_BLOB;
|
||||||
|
HttpRequest httpMethod = processor.createRequest(method, new Object[] {
|
||||||
|
URI.create("http://uploader"), "token", "adriansmovies", blob });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "uploader");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/Upload.ashx");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getQuery(),
|
||||||
|
"output=json&uploadToken=token&destFolderPath=adriansmovies");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 2);
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||||
|
.singletonList(AddBlobEntityAsMultipartFormTest.EXPECTS.length() + ""));
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||||
|
.singletonList("multipart/form-data; boundary="
|
||||||
|
+ AddBlobEntityAsMultipartFormTest.BOUNDRY));
|
||||||
|
assertEquals(Utils.toStringAndClose((InputStream) httpMethod.getEntity()),
|
||||||
|
AddBlobEntityAsMultipartFormTest.EXPECTS);
|
||||||
|
assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(),
|
||||||
|
ReturnVoidIf2xx.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSetMetadata() throws SecurityException, NoSuchMethodException, IOException {
|
||||||
|
Method method = SDNConnection.class.getMethod("setMetadata", String.class, String.class,
|
||||||
|
Multimap.class);
|
||||||
|
HttpRequest httpMethod = processor.createRequest(method, new Object[] { "adriansmovies",
|
||||||
|
"sushi.avi", ImmutableMultimap.of("Chef", "Kawasaki") });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/Metadata/SetMetadata.ashx");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getQuery(),
|
||||||
|
"output=json&path=adriansmovies/sushi.avi&metadata=chef:Kawasaki");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||||
|
.singletonList(0 + ""));
|
||||||
|
assertEquals(httpMethod.getEntity(), null);
|
||||||
|
assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(),
|
||||||
|
ReturnVoidIf2xx.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
void setupFactory() {
|
||||||
|
Injector injector = Guice.createInjector(new AbstractModule() {
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(URI.class).annotatedWith(SDN.class)
|
||||||
|
.toInstance(URI.create("http://localhost:8080"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@SessionToken
|
||||||
|
@Provides
|
||||||
|
String authTokenProvider() {
|
||||||
|
return "session-token";
|
||||||
|
}
|
||||||
|
}, new RestModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||||
|
new JavaUrlHttpCommandExecutorServiceModule());
|
||||||
|
processor = injector.getInstance(Key
|
||||||
|
.get(new TypeLiteral<RestAnnotationProcessor<SDNConnection>>() {
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package org.jclouds.nirvanix.sdn.decorators;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.ws.rs.HttpMethod;
|
||||||
|
import javax.ws.rs.ext.RuntimeDelegate;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.rest.internal.RuntimeDelegateImpl;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code AddMetadataAsQueryParams}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "sdn.AddMetadataAsQueryParamsTest")
|
||||||
|
public class AddMetadataAsQueryParamsTest {
|
||||||
|
static {
|
||||||
|
RuntimeDelegate.setInstance(new RuntimeDelegateImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
|
public void testMustBeMap() {
|
||||||
|
AddMetadataAsQueryParams binder = new AddMetadataAsQueryParams();
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||||
|
request = binder.decorateRequest(request, new File("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCorrect() {
|
||||||
|
AddMetadataAsQueryParams binder = new AddMetadataAsQueryParams();
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost"));
|
||||||
|
request = binder.decorateRequest(request, ImmutableMultimap.of("imageName", "foo", "serverId", "2") );
|
||||||
|
assertEquals(request.getEndpoint().getQuery(), "metadata=imagename:foo&metadata=serverid:2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class })
|
||||||
|
public void testNullIsBad() {
|
||||||
|
AddMetadataAsQueryParams binder = new AddMetadataAsQueryParams();
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost"));
|
||||||
|
request = binder.decorateRequest(request,null );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.nirvanix.sdn.filters;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.ws.rs.HttpMethod;
|
||||||
|
import javax.ws.rs.ext.RuntimeDelegate;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.nirvanix.sdn.SessionToken;
|
||||||
|
import org.jclouds.rest.internal.RuntimeDelegateImpl;
|
||||||
|
import org.jclouds.util.DateService;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.DataProvider;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
@Test(groups = "unit", testName = "sdn.AddSessionTokenToRequestTest")
|
||||||
|
public class AddSessionTokenToRequestTest {
|
||||||
|
|
||||||
|
private Injector injector;
|
||||||
|
private AddSessionTokenToRequest filter;
|
||||||
|
|
||||||
|
@DataProvider
|
||||||
|
public Object[][] dataProvider() {
|
||||||
|
return new Object[][] { { new HttpRequest(HttpMethod.GET, URI.create("https://host:443")) },
|
||||||
|
{ new HttpRequest(HttpMethod.GET, URI.create("https://host/path")) },
|
||||||
|
{ new HttpRequest(HttpMethod.GET, URI.create("https://host/?query"))
|
||||||
|
|
||||||
|
} };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dataProvider = "dataProvider")
|
||||||
|
public void testRequests(HttpRequest request) {
|
||||||
|
String token = filter.getSessionToken();
|
||||||
|
|
||||||
|
String query = request.getEndpoint().getQuery();
|
||||||
|
request = filter.filter(request);
|
||||||
|
assertEquals(request.getEndpoint().getQuery(), query == null ? "sessionToken=" + token
|
||||||
|
: query + "&sessionToken=" + token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUpdatesOnlyOncePerSecond() throws NoSuchMethodException, InterruptedException {
|
||||||
|
String token = filter.getSessionToken();
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
filter.updateIfTimeOut();
|
||||||
|
assert token.equals(filter.getSessionToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* before class, as we need to ensure that the filter is threadsafe.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@BeforeClass
|
||||||
|
protected void createFilter() {
|
||||||
|
injector = Guice.createInjector(new AbstractModule() {
|
||||||
|
|
||||||
|
protected void configure() {
|
||||||
|
RuntimeDelegate.setInstance(new RuntimeDelegateImpl());
|
||||||
|
bind(DateService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@SessionToken
|
||||||
|
@Provides
|
||||||
|
String authTokenProvider() {
|
||||||
|
return System.currentTimeMillis() + "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
filter = injector.getInstance(AddSessionTokenToRequest.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.nirvanix.sdn.functions;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.config.ParserModule;
|
||||||
|
import org.jclouds.nirvanix.sdn.domain.UploadInfo;
|
||||||
|
import org.jclouds.util.DateService;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code ParseUploadInfoFromJsonResponse}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "sdn.ParseUploadInfoFromJsonResponse")
|
||||||
|
public class ParseUploadInfoFromJsonResponseTest {
|
||||||
|
|
||||||
|
Injector i = Guice.createInjector(new ParserModule());
|
||||||
|
DateService dateService = new DateService();
|
||||||
|
|
||||||
|
public void testApplyInputStreamDetails() throws UnknownHostException {
|
||||||
|
InputStream is = getClass().getResourceAsStream("/authtoken.json");
|
||||||
|
|
||||||
|
ParseUploadInfoFromJsonResponse parser = new ParseUploadInfoFromJsonResponse(i
|
||||||
|
.getInstance(Gson.class));
|
||||||
|
UploadInfo response = parser.apply(is);
|
||||||
|
assertEquals(response.getHost(), URI.create("https://node1.nirvanix.com"));
|
||||||
|
assertEquals(response.getToken(), "siR-ALYd~BEcJ8GR2tE~oX3SEHO8~2WXKT5xjFk~YLS5OvJyHI21TN34rQ");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1
nirvanix/sdn/core/src/test/resources/authtoken.json
Normal file
1
nirvanix/sdn/core/src/test/resources/authtoken.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"ResponseCode":0,"GetStorageNode":{"UploadHost":"node1.nirvanix.com","UploadToken":"siR-ALYd~BEcJ8GR2tE~oX3SEHO8~2WXKT5xjFk~YLS5OvJyHI21TN34rQ"}}
|
Loading…
x
Reference in New Issue
Block a user