mirror of https://github.com/apache/jclouds.git
Issue 97: webdav compatible mapping. when slashes are present in blob names, create subfolders accordingly
git-svn-id: http://jclouds.googlecode.com/svn/trunk@1949 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
c228add243
commit
22e949343e
|
@ -43,15 +43,17 @@ import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
|||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||
import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
|
||||
import org.jclouds.mezeo.pcs2.endpoints.WebDAV;
|
||||
import org.jclouds.mezeo.pcs2.functions.AddMetadataAndParseResourceIdIntoBytes;
|
||||
import org.jclouds.mezeo.pcs2.functions.AssembleBlobFromContentAndMetadataCache;
|
||||
import org.jclouds.mezeo.pcs2.functions.CreateSubFolderIfNotExistsAndGetResourceId;
|
||||
import org.jclouds.mezeo.pcs2.functions.ContainerAndFileNameToResourceId;
|
||||
import org.jclouds.mezeo.pcs2.functions.ContainerNameToResourceId;
|
||||
import org.jclouds.mezeo.pcs2.functions.InvalidateContainerNameCacheAndReturnTrueIf2xx;
|
||||
import org.jclouds.mezeo.pcs2.functions.InvalidatePCSKeyCacheAndReturnVoidIf2xx;
|
||||
import org.jclouds.mezeo.pcs2.functions.ReturnFalseIfContainerNotFound;
|
||||
import org.jclouds.mezeo.pcs2.functions.ReturnTrueIfContainerAlreadyExists;
|
||||
import org.jclouds.mezeo.pcs2.xml.FileListToContainerMetadataListHandler;
|
||||
import org.jclouds.mezeo.pcs2.xml.CachingFileListToContainerMetadataListHandler;
|
||||
import org.jclouds.mezeo.pcs2.xml.FileListToFileMetadataListHandler;
|
||||
import org.jclouds.mezeo.pcs2.xml.FileMetadataHandler;
|
||||
import org.jclouds.rest.Endpoint;
|
||||
|
@ -78,7 +80,7 @@ import org.jclouds.rest.XMLResponseParser;
|
|||
public interface PCSBlobStore extends BlobStore<ContainerMetadata, FileMetadata, PCSFile> {
|
||||
|
||||
@GET
|
||||
@XMLResponseParser(FileListToContainerMetadataListHandler.class)
|
||||
@XMLResponseParser(CachingFileListToContainerMetadataListHandler.class)
|
||||
@Headers(keys = "X-Cloud-Depth", values = "2")
|
||||
@Path("/contents")
|
||||
@Endpoint(RootContainer.class)
|
||||
|
@ -117,8 +119,9 @@ public interface PCSBlobStore extends BlobStore<ContainerMetadata, FileMetadata,
|
|||
@Path("/containers/{containerResourceId}/contents")
|
||||
@Endpoint(PCS.class)
|
||||
@ResponseParser(AddMetadataAndParseResourceIdIntoBytes.class)
|
||||
Future<byte[]> putBlob(
|
||||
@PathParam("containerResourceId") @ParamParser(ContainerNameToResourceId.class) String containerName,
|
||||
@PathParam("containerResourceId")
|
||||
@ParamParser(CreateSubFolderIfNotExistsAndGetResourceId.class)
|
||||
Future<byte[]> putBlob(String containerName,
|
||||
@EntityParam(PCSFileAsMultipartFormBinder.class) PCSFile object);
|
||||
|
||||
@DELETE
|
||||
|
@ -132,12 +135,10 @@ public interface PCSBlobStore extends BlobStore<ContainerMetadata, FileMetadata,
|
|||
|
||||
@GET
|
||||
@ExceptionParser(ThrowKeyNotFoundOn404.class)
|
||||
@Path("/files/{resourceId}/content")
|
||||
@PathParam("resourceId")
|
||||
@Endpoint(PCS.class)
|
||||
@ParamParser(ContainerAndFileNameToResourceId.class)
|
||||
@Path("{container}/{key}")
|
||||
@Endpoint(WebDAV.class)
|
||||
@ResponseParser(AssembleBlobFromContentAndMetadataCache.class)
|
||||
Future<PCSFile> getBlob(String container, String key);
|
||||
Future<PCSFile> getBlob(@PathParam("container") String container, @PathParam("key") String key);
|
||||
|
||||
@GET
|
||||
@ExceptionParser(ThrowKeyNotFoundOn404.class)
|
||||
|
|
|
@ -77,6 +77,11 @@ public interface PCSConnection {
|
|||
@Endpoint(RootContainer.class)
|
||||
Future<URI> createContainer(@EntityParam(CreateContainerBinder.class) String container);
|
||||
|
||||
|
||||
@POST
|
||||
@Path("/contents")
|
||||
Future<URI> createContainer(@Endpoint URI parent, @EntityParam(CreateContainerBinder.class) String container);
|
||||
|
||||
@DELETE
|
||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||
Future<Void> deleteContainer(@Endpoint URI container);
|
||||
|
@ -87,6 +92,12 @@ public interface PCSConnection {
|
|||
@Path("/contents")
|
||||
Future<? extends SortedSet<FileMetadata>> listFiles(@Endpoint URI container);
|
||||
|
||||
@GET
|
||||
@XMLResponseParser(FileListToContainerMetadataListHandler.class)
|
||||
@Headers(keys = "X-Cloud-Depth", values = "2")
|
||||
@Path("/contents")
|
||||
Future<? extends SortedSet<ContainerMetadata>> listContainers(@Endpoint URI container);
|
||||
|
||||
@POST
|
||||
@Path("/contents")
|
||||
Future<URI> uploadFile(@Endpoint URI container,
|
||||
|
|
|
@ -24,18 +24,21 @@
|
|||
package org.jclouds.mezeo.pcs2;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
|
||||
import org.jclouds.http.filters.BasicAuthentication;
|
||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||
import org.jclouds.mezeo.pcs2.functions.AddEntryIntoMultiMap;
|
||||
import org.jclouds.rest.Endpoint;
|
||||
import org.jclouds.rest.EntityParam;
|
||||
import org.jclouds.rest.ExceptionParser;
|
||||
import org.jclouds.rest.RequestFilters;
|
||||
import org.jclouds.rest.ResponseParser;
|
||||
import org.jclouds.rest.SkipEncoding;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
* Provides access to Mezeo PCS v2 via their REST API.
|
||||
* <p/>
|
||||
|
@ -50,10 +53,9 @@ import org.jclouds.rest.SkipEncoding;
|
|||
public interface PCSUtil {
|
||||
|
||||
@PUT
|
||||
@ExceptionParser(ReturnFalseOn404.class)
|
||||
boolean put(@Endpoint URI resource, @EntityParam String value);
|
||||
Future<Void> put(@Endpoint URI resource, @EntityParam String value);
|
||||
|
||||
@GET
|
||||
String get(@Endpoint URI resource);
|
||||
|
||||
@ResponseParser(AddEntryIntoMultiMap.class)
|
||||
Future<Void> addEntryToMultiMap(Multimap<String, String> map, String key, @Endpoint URI value);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ import org.jclouds.blobstore.domain.Blob;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.MultipartForm;
|
||||
import org.jclouds.http.MultipartForm.Part;
|
||||
import org.jclouds.mezeo.pcs2.functions.Key;
|
||||
import org.jclouds.mezeo.pcs2.util.PCSUtils;
|
||||
import org.jclouds.rest.binders.EntityBinder;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
|
@ -50,12 +52,11 @@ public class PCSFileAsMultipartFormBinder implements EntityBinder {
|
|||
|
||||
public void addEntityToRequest(Object entity, HttpRequest request) {
|
||||
Blob<?> object = (Blob<?>) entity;
|
||||
|
||||
Multimap<String, String> partHeaders = ImmutableMultimap.of("Content-Disposition",
|
||||
String.format("form-data; name=\"%s\"; filename=\"%s\"", object.getKey(), object
|
||||
.getKey()), HttpHeaders.CONTENT_TYPE, checkNotNull(object.getMetadata()
|
||||
.getContentType(), "object.metadata.contentType()"));
|
||||
|
||||
Key key = PCSUtils.parseKey(new Key("junk", object.getKey()));
|
||||
Multimap<String, String> partHeaders = ImmutableMultimap.of("Content-Disposition", String
|
||||
.format("form-data; name=\"%s\"; filename=\"%s\"", key.getKey(), key.getKey()),
|
||||
HttpHeaders.CONTENT_TYPE, checkNotNull(object.getMetadata().getContentType(),
|
||||
"object.metadata.contentType()"));
|
||||
Object data = checkNotNull(object.getData(), "object.getData()");
|
||||
|
||||
Part part;
|
||||
|
|
|
@ -88,7 +88,7 @@ public class PCSContextModule extends AbstractModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
public ConcurrentMap<String, String> provideConcurrentMap(FindIdInContainerList finder) {
|
||||
return new MapMaker().concurrencyLevel(32).expiration(30, TimeUnit.SECONDS).makeComputingMap(
|
||||
return new MapMaker().expiration(30, TimeUnit.SECONDS).makeComputingMap(
|
||||
finder);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.jclouds.mezeo.pcs2.endpoints.Recyclebin;
|
|||
import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
|
||||
import org.jclouds.mezeo.pcs2.endpoints.Shares;
|
||||
import org.jclouds.mezeo.pcs2.endpoints.Tags;
|
||||
import org.jclouds.mezeo.pcs2.endpoints.WebDAV;
|
||||
import org.jclouds.mezeo.pcs2.handlers.PCSClientErrorRetryHandler;
|
||||
import org.jclouds.mezeo.pcs2.reference.PCSConstants;
|
||||
import org.jclouds.rest.RestClientFactory;
|
||||
|
@ -99,7 +100,8 @@ public class RestPCSBlobStoreModule extends AbstractModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected BlobStore<ContainerMetadata, FileMetadata, PCSFile> provideBlobStore(RestClientFactory factory) {
|
||||
protected BlobStore<ContainerMetadata, FileMetadata, PCSFile> provideBlobStore(
|
||||
RestClientFactory factory) {
|
||||
return factory.create(PCSBlobStore.class);
|
||||
}
|
||||
|
||||
|
@ -117,6 +119,13 @@ public class RestPCSBlobStoreModule extends AbstractModule {
|
|||
return URI.create(endpoint);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@WebDAV
|
||||
protected URI provideWebDAVURI(@Named(PCSConstants.PROPERTY_PCS2_ENDPOINT) String endpoint) {
|
||||
return URI.create(endpoint.replaceAll("v2", "dav"));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Contacts
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.joda.time.DateTime;
|
|||
public class ContainerMetadata extends org.jclouds.blobstore.domain.ContainerMetadata implements
|
||||
PCSObject {
|
||||
private URI url;
|
||||
private URI parent;
|
||||
private DateTime created;
|
||||
private DateTime lastModified;
|
||||
private DateTime accessed;
|
||||
|
@ -46,15 +47,15 @@ public class ContainerMetadata extends org.jclouds.blobstore.domain.ContainerMet
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ContainerMetadata [name=" + name + ", url=" + url + ", accessed=" + accessed
|
||||
+ ", bytes=" + bytes + ", created=" + created + ", isInProject=" + isInProject
|
||||
+ ", isShared=" + isShared + ", lastModified=" + lastModified + ", owner=" + owner
|
||||
+ ", version=" + version + "]";
|
||||
return "ContainerMetadata [name=" + name + ", url=" + url + ", parent=" + parent + ", owner="
|
||||
+ owner + ", version=" + version + ", bytes=" + bytes + ", isInProject="
|
||||
+ isInProject + ", isShared=" + isShared + ", created=" + created
|
||||
+ ", lastModified=" + lastModified + ", accessed=" + accessed + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int prime = 31;
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((accessed == null) ? 0 : accessed.hashCode());
|
||||
result = prime * result + (int) (bytes ^ (bytes >>> 32));
|
||||
|
@ -63,6 +64,7 @@ public class ContainerMetadata extends org.jclouds.blobstore.domain.ContainerMet
|
|||
result = prime * result + (isShared ? 1231 : 1237);
|
||||
result = prime * result + ((lastModified == null) ? 0 : lastModified.hashCode());
|
||||
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
|
||||
result = prime * result + ((parent == null) ? 0 : parent.hashCode());
|
||||
result = prime * result + ((url == null) ? 0 : url.hashCode());
|
||||
result = prime * result + version;
|
||||
return result;
|
||||
|
@ -103,6 +105,11 @@ public class ContainerMetadata extends org.jclouds.blobstore.domain.ContainerMet
|
|||
return false;
|
||||
} else if (!owner.equals(other.owner))
|
||||
return false;
|
||||
if (parent == null) {
|
||||
if (other.parent != null)
|
||||
return false;
|
||||
} else if (!parent.equals(other.parent))
|
||||
return false;
|
||||
if (url == null) {
|
||||
if (other.url != null)
|
||||
return false;
|
||||
|
@ -112,15 +119,16 @@ public class ContainerMetadata extends org.jclouds.blobstore.domain.ContainerMet
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public ContainerMetadata() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ContainerMetadata(String name, URI url, DateTime created, DateTime lastModified,
|
||||
DateTime accessed, String owner, boolean isShared, boolean isInProject, int version,
|
||||
long bytes) {
|
||||
|
||||
public ContainerMetadata(String name, URI url, URI parent, DateTime created,
|
||||
DateTime lastModified, DateTime accessed, String owner, boolean isShared,
|
||||
boolean isInProject, int version, long bytes) {
|
||||
super(name);
|
||||
this.setParent(parent);
|
||||
this.url = url;
|
||||
this.created = created;
|
||||
this.lastModified = lastModified;
|
||||
|
@ -168,4 +176,12 @@ public class ContainerMetadata extends org.jclouds.blobstore.domain.ContainerMet
|
|||
return bytes;
|
||||
}
|
||||
|
||||
public void setParent(URI parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public URI getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
*
|
||||
* 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.mezeo.pcs2.endpoints;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
/**
|
||||
* Related to a resource of type WebDAV
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||
@Qualifier
|
||||
public @interface WebDAV {
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package org.jclouds.mezeo.pcs2.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.ReturnStringIf200;
|
||||
import org.jclouds.rest.RestContext;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class AddEntryIntoMultiMap implements Function<HttpResponse, Void>, RestContext {
|
||||
ReturnStringIf200 returnIf200;
|
||||
|
||||
@Inject
|
||||
private AddEntryIntoMultiMap(ReturnStringIf200 returnIf200) {
|
||||
this.returnIf200 = returnIf200;
|
||||
}
|
||||
|
||||
private Object[] args;
|
||||
private HttpRequest request;
|
||||
|
||||
static final Void v;
|
||||
static {
|
||||
Constructor<Void> cv;
|
||||
try {
|
||||
cv = Void.class.getDeclaredConstructor();
|
||||
cv.setAccessible(true);
|
||||
v = cv.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new Error("Error setting up class", e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Void apply(HttpResponse from)
|
||||
|
||||
{
|
||||
checkState(args != null, "args should be initialized at this point");
|
||||
Multimap<String, String> map = null;
|
||||
String key = null;
|
||||
for (Object arg : args) {
|
||||
if (arg instanceof Multimap)
|
||||
map = (Multimap<String, String>) arg;
|
||||
else if (arg instanceof String)
|
||||
key = arg.toString();
|
||||
}
|
||||
checkState(map != null, "No Multimap found in args, improper method declarations");
|
||||
checkState(key != null, "No String found in args, improper method declarations");
|
||||
|
||||
map.put(key, returnIf200.apply(from).trim());
|
||||
return v;
|
||||
}
|
||||
|
||||
public Object[] getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
public HttpRequest getRequest() {
|
||||
return request;
|
||||
}
|
||||
|
||||
public void setContext(HttpRequest request, Object[] args) {
|
||||
this.request = request;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
}
|
|
@ -27,12 +27,18 @@ import static com.google.common.base.Preconditions.checkState;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
import org.jclouds.blobstore.internal.BlobRuntimeException;
|
||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
|
@ -44,6 +50,7 @@ import org.jclouds.rest.RestContext;
|
|||
import org.jclouds.util.Utils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* PCS does not return an eTag header. As such, we'll make one out of the object id.
|
||||
|
@ -58,6 +65,13 @@ public class AddMetadataAndParseResourceIdIntoBytes implements Function<HttpResp
|
|||
private Object[] args;
|
||||
private HttpRequest request;
|
||||
|
||||
/**
|
||||
* maximum duration of an blob Request
|
||||
*/
|
||||
@Inject(optional = true)
|
||||
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT)
|
||||
protected long requestTimeoutMilliseconds = 30000;
|
||||
|
||||
@Inject
|
||||
public AddMetadataAndParseResourceIdIntoBytes(PCSUtil util) {
|
||||
this.util = util;
|
||||
|
@ -77,11 +91,22 @@ public class AddMetadataAndParseResourceIdIntoBytes implements Function<HttpResp
|
|||
String toParse = Utils.toStringAndClose(from.getContent());
|
||||
logger.trace("%s: received the following response: %s", from, toParse);
|
||||
URI uri = URI.create(toParse.trim());
|
||||
|
||||
Set<Future<Void>> puts = Sets.newHashSet();
|
||||
for (Entry<String, String> entry : file.getMetadata().getUserMetadata().entries()) {
|
||||
URI key = UriBuilder.fromUri(uri).path(String.format("metadata/%s", entry.getKey()))
|
||||
.build();
|
||||
util.put(key, entry.getValue());
|
||||
puts.add(util.put(key, entry.getValue()));
|
||||
}
|
||||
for (Future<Void> put : puts) {
|
||||
try {
|
||||
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
throw new BlobRuntimeException("Error putting metadata for file: " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
return PCSUtils.getEtag(uri);
|
||||
} catch (IOException e) {
|
||||
throw new HttpResponseException("couldn't parse url from response", null, from, e);
|
||||
|
|
|
@ -59,9 +59,9 @@ public class ContainerAndFileNameToResourceId implements Function<Object, String
|
|||
Object[] args = (Object[]) from;
|
||||
checkArgument(args[0] instanceof String, "arg[0] must be a container name");
|
||||
checkArgument(args[1] instanceof String, "arg[1] must be a pcsfile name (key)");
|
||||
|
||||
String container = args[0].toString();
|
||||
String key = args[1].toString();
|
||||
|
||||
try {
|
||||
return cachedFinder.get(new Key(container, key));
|
||||
} catch (ComputationException e) {
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/**
|
||||
*
|
||||
* 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.mezeo.pcs2.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.internal.BlobRuntimeException;
|
||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||
import org.jclouds.mezeo.pcs2.PCSConnection;
|
||||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||
import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
|
||||
import org.jclouds.mezeo.pcs2.util.PCSUtils;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ComputationException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CreateSubFolderIfNotExistsAndGetResourceId implements Function<Object, String> {
|
||||
|
||||
/**
|
||||
* maximum duration of an blob Request
|
||||
*/
|
||||
@Inject(optional = true)
|
||||
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT)
|
||||
protected long requestTimeoutMilliseconds = 30000;
|
||||
|
||||
private final ConcurrentMap<String, String> finder;
|
||||
private final PCSConnection blobStore;
|
||||
private final URI rootContainer;
|
||||
|
||||
@Inject
|
||||
public CreateSubFolderIfNotExistsAndGetResourceId(PCSConnection blobStore,
|
||||
ConcurrentMap<String, String> finder, @RootContainer URI rootContainer) {
|
||||
this.finder = finder;
|
||||
this.blobStore = blobStore;
|
||||
this.rootContainer = rootContainer;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public String apply(Object from) {
|
||||
checkState(checkNotNull(from, "args") instanceof Object[],
|
||||
"this must be applied to a method!");
|
||||
Object[] args = (Object[]) from;
|
||||
checkArgument(args[0] instanceof String, "arg[0] must be a container name");
|
||||
checkArgument(args[1] instanceof Blob, "arg[1] must be a pcsfile");
|
||||
Key key = PCSUtils.parseKey(new Key(args[0].toString(), ((Blob) args[1]).getKey()));
|
||||
try {
|
||||
return finder.get(key.getContainer());
|
||||
} catch (ComputationException e) {
|
||||
if (e.getCause() instanceof ContainerNotFoundException) {
|
||||
String[] containerTree = key.getContainer().split("/");
|
||||
|
||||
SortedSet<ContainerMetadata> response = blobStore.listContainers();
|
||||
URI containerUri;
|
||||
try {
|
||||
containerUri = urlForNameInListOrCreate(rootContainer, containerTree[0],
|
||||
response);
|
||||
} catch (Exception e1) {
|
||||
|
||||
Utils.<ContainerNotFoundException> rethrowIfRuntimeOrSameType(e1);
|
||||
throw new BlobRuntimeException("error creating container at: " + containerTree[0], e1);
|
||||
}
|
||||
if (containerTree.length != 1) {
|
||||
for (int i = 1; i < containerTree.length; i++) {
|
||||
try {
|
||||
response = blobStore.listContainers(containerUri).get(
|
||||
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||
containerUri = urlForNameInListOrCreate(containerUri, containerTree[i],
|
||||
response);
|
||||
} catch (Exception e2) {
|
||||
Utils.<ContainerNotFoundException> rethrowIfRuntimeOrSameType(e2);
|
||||
throw new BlobRuntimeException("error listing container at: " + containerUri,
|
||||
e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return PCSUtils.getContainerId(containerUri);
|
||||
}
|
||||
|
||||
Utils.<ContainerNotFoundException> rethrowIfRuntimeOrSameType(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
URI urlForNameInListOrCreate(URI parent, String toFind,
|
||||
SortedSet<ContainerMetadata> containerMetadataList) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
for (ContainerMetadata data : containerMetadataList) {
|
||||
if (toFind.equals(data.getName())) {
|
||||
return data.getUrl();
|
||||
}
|
||||
}
|
||||
return blobStore.createContainer(parent, toFind).get(requestTimeoutMilliseconds,
|
||||
TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
}
|
|
@ -23,38 +23,76 @@
|
|||
*/
|
||||
package org.jclouds.mezeo.pcs2.functions;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.blobstore.internal.BlobRuntimeException;
|
||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||
import org.jclouds.mezeo.pcs2.PCSConnection;
|
||||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||
import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
|
||||
import org.jclouds.mezeo.pcs2.util.PCSUtils;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
|
||||
public class FindIdInContainerList implements Function<String, String> {
|
||||
private PCSConnection connection;
|
||||
private final PCSConnection connection;
|
||||
private final URI rootContainerUri;
|
||||
|
||||
/**
|
||||
* maximum duration of an blob Request
|
||||
*/
|
||||
@Inject(optional = true)
|
||||
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT)
|
||||
protected long requestTimeoutMilliseconds = 30000;
|
||||
|
||||
@Inject
|
||||
public FindIdInContainerList(PCSConnection connection) {
|
||||
public FindIdInContainerList(PCSConnection connection, @RootContainer URI rootContainerURI) {
|
||||
this.connection = connection;
|
||||
this.rootContainerUri = rootContainerURI;
|
||||
}
|
||||
|
||||
public String apply(String key) {
|
||||
SortedSet<ContainerMetadata> response = connection.listContainers();
|
||||
return idForNameInListOrException(key, response);
|
||||
String[] containerTree = key.split("/");
|
||||
URI containerUri = rootContainerUri;
|
||||
try {
|
||||
containerUri = urlForNameInListOrException(containerTree[0], rootContainerUri, connection
|
||||
.listContainers(rootContainerUri).get(requestTimeoutMilliseconds,
|
||||
TimeUnit.MILLISECONDS));
|
||||
if (containerTree.length != 1) {
|
||||
for (int i = 1; i < containerTree.length; i++) {
|
||||
containerUri = urlForNameInListOrException(containerTree[i], containerUri,
|
||||
listContainers(containerUri));
|
||||
}
|
||||
}
|
||||
return PCSUtils.getContainerId(containerUri);
|
||||
} catch (Exception e) {
|
||||
Utils.<ContainerNotFoundException> rethrowIfRuntimeOrSameType(e);
|
||||
throw new BlobRuntimeException("error listing container at: " + containerUri, e);
|
||||
}
|
||||
}
|
||||
|
||||
private SortedSet<ContainerMetadata> listContainers(URI containerUri)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
return connection.listContainers(containerUri).get(requestTimeoutMilliseconds,
|
||||
TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String idForNameInListOrException(String toFind,
|
||||
URI urlForNameInListOrException(String toFind, URI parent,
|
||||
SortedSet<ContainerMetadata> containerMetadataList) {
|
||||
for (ContainerMetadata data : containerMetadataList) {
|
||||
if (toFind.equals(data.getName())) {
|
||||
String path = data.getUrl().getPath();
|
||||
int indexAfterContainersSlash = path.indexOf("containers/") + "containers/".length();
|
||||
return path.substring(indexAfterContainersSlash);
|
||||
if (toFind.equals(data.getName()) && parent.equals(data.getParent())) {
|
||||
return data.getUrl();
|
||||
}
|
||||
}
|
||||
throw new ContainerNotFoundException(toFind);
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.jclouds.http.HttpException;
|
|||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||
import org.jclouds.mezeo.pcs2.util.PCSUtils;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
@ -50,6 +51,7 @@ public class FindIdInFileList implements Function<Key, String> {
|
|||
}
|
||||
|
||||
public String apply(Key key) {
|
||||
key = PCSUtils.parseKey(key);
|
||||
SortedSet<FileMetadata> response;
|
||||
try {
|
||||
response = connection.listBlobs(key.getContainer()).get(10, TimeUnit.SECONDS);
|
||||
|
|
|
@ -26,6 +26,7 @@ package org.jclouds.mezeo.pcs2.util;
|
|||
import java.net.URI;
|
||||
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.mezeo.pcs2.functions.Key;
|
||||
|
||||
/**
|
||||
* Utilities for PCS connections.
|
||||
|
@ -44,4 +45,20 @@ public class PCSUtils {
|
|||
return eTag;
|
||||
}
|
||||
|
||||
public static Key parseKey(Key key) {
|
||||
|
||||
if (key.getKey().indexOf('/') != -1) {
|
||||
String container = key.getContainer() + '/'
|
||||
+ key.getKey().substring(0, key.getKey().lastIndexOf('/'));
|
||||
String newKey = key.getKey().substring(key.getKey().lastIndexOf('/')+1);
|
||||
key = new Key(container.replaceAll("//", "/"), newKey);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public static String getContainerId(URI url) {
|
||||
String path = url.getPath();
|
||||
int indexAfterContainersSlash = path.indexOf("containers/") + "containers/".length();
|
||||
return path.substring(indexAfterContainersSlash);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
*
|
||||
* 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.mezeo.pcs2.xml;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||
import org.jclouds.mezeo.pcs2.util.PCSUtils;
|
||||
import org.jclouds.util.DateService;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CachingFileListToContainerMetadataListHandler extends
|
||||
FileListToContainerMetadataListHandler {
|
||||
private final ConcurrentMap<String, String> cache;
|
||||
|
||||
@Inject
|
||||
public CachingFileListToContainerMetadataListHandler(ConcurrentMap<String, String> cache,
|
||||
DateService dateParser) {
|
||||
super(dateParser);
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<ContainerMetadata> getResult() {
|
||||
SortedSet<ContainerMetadata> result = super.getResult();
|
||||
for (ContainerMetadata md : result) {
|
||||
cache.put(md.getName(), PCSUtils.getContainerId(md.getUrl()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -26,9 +26,11 @@ package org.jclouds.mezeo.pcs2.xml;
|
|||
import java.net.URI;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.joda.time.DateTime;
|
||||
|
@ -43,6 +45,20 @@ import com.google.common.collect.Sets;
|
|||
public class FileListToContainerMetadataListHandler extends
|
||||
ParseSax.HandlerWithResult<SortedSet<ContainerMetadata>> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FileListToContainerMetadataListHandler [containerMetadata=" + containerMetadata
|
||||
+ ", currentAccessed=" + currentAccessed + ", currentBytes=" + currentBytes
|
||||
+ ", currentCreated=" + currentCreated + ", currentInproject=" + currentInproject
|
||||
+ ", currentModified=" + currentModified + ", currentName=" + currentName
|
||||
+ ", currentOwner=" + currentOwner + ", currentShared=" + currentShared
|
||||
+ ", currentText=" + currentText + ", currentUrl=" + currentUrl
|
||||
+ ", currentVersion=" + currentVersion + ", dateParser=" + dateParser + "]";
|
||||
}
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private SortedSet<ContainerMetadata> containerMetadata = Sets.newTreeSet();
|
||||
private URI currentUrl;
|
||||
private String currentName;
|
||||
|
@ -59,6 +75,11 @@ public class FileListToContainerMetadataListHandler extends
|
|||
|
||||
private final DateService dateParser;
|
||||
|
||||
boolean inContainer = false;
|
||||
boolean ignore = false;
|
||||
|
||||
private URI currentParent;
|
||||
|
||||
@Inject
|
||||
public FileListToContainerMetadataListHandler(DateService dateParser) {
|
||||
this.dateParser = dateParser;
|
||||
|
@ -72,16 +93,54 @@ public class FileListToContainerMetadataListHandler extends
|
|||
public void startElement(String uri, String localName, String qName, Attributes attributes)
|
||||
throws SAXException {
|
||||
if (qName.equals("container")) {
|
||||
if (inContainer) {
|
||||
ignore = true;
|
||||
return;
|
||||
}
|
||||
inContainer = true;
|
||||
int index = attributes.getIndex("xlink:href");
|
||||
if (index != -1) {
|
||||
currentUrl = URI.create(attributes.getValue(index));
|
||||
}
|
||||
} else if (qName.equals("parent") && !ignore) {
|
||||
int index = attributes.getIndex("xlink:href");
|
||||
if (index != -1) {
|
||||
currentParent = URI.create(attributes.getValue(index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
if (qName.equals("name")) {
|
||||
if (ignore) {
|
||||
currentText = new StringBuilder();
|
||||
if (qName.equals("container")) {
|
||||
ignore = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (qName.equals("container")) {
|
||||
inContainer = false;
|
||||
try {
|
||||
containerMetadata.add(new ContainerMetadata(currentName, currentUrl, currentParent,
|
||||
currentCreated, currentModified, currentAccessed, currentOwner, currentShared,
|
||||
currentInproject, currentVersion, currentBytes));
|
||||
} catch (RuntimeException e) {
|
||||
logger.error(e, "error creating object! current state %s", this);
|
||||
throw e;
|
||||
}
|
||||
currentUrl = null;
|
||||
currentParent = null;
|
||||
currentName = null;
|
||||
currentCreated = null;
|
||||
currentInproject = false;
|
||||
currentModified = null;
|
||||
currentOwner = null;
|
||||
currentVersion = 0;
|
||||
currentShared = false;
|
||||
currentAccessed = null;
|
||||
currentBytes = 0;
|
||||
} else if (qName.equals("name")) {
|
||||
currentName = currentText.toString().trim();
|
||||
} else if (qName.equals("created")) {
|
||||
currentCreated = dateParser.fromSeconds(Long.parseLong(currentText.toString().trim()));
|
||||
|
@ -99,21 +158,6 @@ public class FileListToContainerMetadataListHandler extends
|
|||
currentAccessed = dateParser.fromSeconds(Long.parseLong(currentText.toString().trim()));
|
||||
} else if (qName.equals("bytes")) {
|
||||
currentBytes = Long.parseLong(currentText.toString().trim());
|
||||
} else if (qName.equals("container")) {
|
||||
containerMetadata.add(new ContainerMetadata(currentName, currentUrl, currentCreated,
|
||||
currentModified, currentAccessed, currentOwner, currentShared, currentInproject,
|
||||
currentVersion, currentBytes));
|
||||
currentUrl = null;
|
||||
currentName = null;
|
||||
currentCreated = null;
|
||||
currentInproject = false;
|
||||
currentModified = null;
|
||||
currentOwner = null;
|
||||
currentVersion = 0;
|
||||
currentShared = false;
|
||||
currentAccessed = null;
|
||||
currentBytes = 0;
|
||||
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
|
|
@ -24,17 +24,25 @@
|
|||
package org.jclouds.mezeo.pcs2.xml;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.blobstore.internal.BlobRuntimeException;
|
||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||
import org.jclouds.mezeo.pcs2.PCSUtil;
|
||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.jclouds.util.Utils;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -43,6 +51,13 @@ public class FileMetadataHandler extends BaseFileMetadataHandler<FileMetadata> {
|
|||
private final PCSUtil util;
|
||||
private FileMetadata fileMetadata = null;
|
||||
protected Multimap<String, String> userMetadata = HashMultimap.create();
|
||||
Set<Future<Void>> puts = Sets.newHashSet();
|
||||
/**
|
||||
* maximum duration of an blob Request
|
||||
*/
|
||||
@Inject(optional = true)
|
||||
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT)
|
||||
protected long requestTimeoutMilliseconds = 30000;
|
||||
|
||||
@Inject
|
||||
public FileMetadataHandler(PCSUtil util, DateService dateParser) {
|
||||
|
@ -51,6 +66,14 @@ public class FileMetadataHandler extends BaseFileMetadataHandler<FileMetadata> {
|
|||
}
|
||||
|
||||
public FileMetadata getResult() {
|
||||
for (Future<Void> put : puts) {
|
||||
try {
|
||||
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
throw new BlobRuntimeException("Error getting metadata", e);
|
||||
}
|
||||
}
|
||||
return fileMetadata;
|
||||
}
|
||||
|
||||
|
@ -66,8 +89,8 @@ public class FileMetadataHandler extends BaseFileMetadataHandler<FileMetadata> {
|
|||
int index = attributes.getIndex("xlink:href");
|
||||
if (index != -1) {
|
||||
String key = attributes.getValue(index).replaceAll(".*/metadata/", "");
|
||||
String value = util.get(URI.create(attributes.getValue(index))).trim();
|
||||
userMetadata.put(key.toLowerCase(), value);
|
||||
puts.add(util.addEntryToMultiMap(userMetadata, key.toLowerCase(), URI.create(attributes
|
||||
.getValue(index))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,15 +51,16 @@ import org.jclouds.http.HttpRequest;
|
|||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.http.filters.BasicAuthentication;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||
import org.jclouds.http.functions.ReturnStringIf200;
|
||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||
import org.jclouds.http.functions.ReturnVoidIf2xx;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.mezeo.pcs2.binders.PCSFileAsMultipartFormBinderTest;
|
||||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||
import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
|
||||
import org.jclouds.mezeo.pcs2.endpoints.WebDAV;
|
||||
import org.jclouds.mezeo.pcs2.functions.AddEntryIntoMultiMap;
|
||||
import org.jclouds.mezeo.pcs2.functions.AddMetadataAndParseResourceIdIntoBytes;
|
||||
import org.jclouds.mezeo.pcs2.functions.AssembleBlobFromContentAndMetadataCache;
|
||||
import org.jclouds.mezeo.pcs2.functions.InvalidateContainerNameCacheAndReturnTrueIf2xx;
|
||||
|
@ -72,7 +73,9 @@ 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.ImmutableSortedSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -124,6 +127,8 @@ public class PCSBlobStoreTest {
|
|||
return ImmutableSortedSet
|
||||
.of(new ContainerMetadata(
|
||||
"mycontainer",
|
||||
URI
|
||||
.create("https://pcsbeta.mezeo.net/v2/containers/7F143552-AAF5-11DE-BBB0-0BC388ED913B"),
|
||||
URI
|
||||
.create("https://pcsbeta.mezeo.net/v2/containers/7F143552-AAF5-11DE-BBB0-0BC388ED913B"),
|
||||
dateService.fromSeconds(1254008225),
|
||||
|
@ -180,6 +185,14 @@ public class PCSBlobStoreTest {
|
|||
return null;
|
||||
}
|
||||
|
||||
public Future<? extends SortedSet<ContainerMetadata>> listContainers(URI container) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Future<URI> createContainer(URI parent, String container) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testListContainers() throws SecurityException, NoSuchMethodException {
|
||||
|
@ -311,8 +324,7 @@ public class PCSBlobStoreTest {
|
|||
HttpRequest httpMethod = processor.createRequest(method, new Object[] { "mycontainer",
|
||||
"testfile.txt" });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(),
|
||||
"/files/9E4C5AFA-A98B-11DE-8B4C-C3884B4A2DA3/content");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/webdav/mycontainer/testfile.txt");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), null);
|
||||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||
|
@ -372,24 +384,25 @@ public class PCSBlobStoreTest {
|
|||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||
.singletonList("application/unknown"));
|
||||
assertEquals("bar", httpMethod.getEntity());
|
||||
assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
|
||||
ReturnFalseOn404.class);
|
||||
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||
assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(),
|
||||
ReturnTrueIf2xx.class);
|
||||
ReturnVoidIf2xx.class);
|
||||
}
|
||||
|
||||
public void testGetMetadata() throws SecurityException, NoSuchMethodException {
|
||||
Method method = PCSUtil.class.getMethod("get", URI.class);
|
||||
public void testAddEntryToMultiMap() throws SecurityException, NoSuchMethodException {
|
||||
Method method = PCSUtil.class.getMethod("addEntryToMultiMap", Multimap.class, String.class,
|
||||
URI.class);
|
||||
|
||||
HttpRequest httpMethod = utilProcessor.createRequest(method, new Object[] {
|
||||
URI.create("http://localhost/pow"), "foo" });
|
||||
HttpRequest httpMethod = utilProcessor
|
||||
.createRequest(method, new Object[] { ImmutableMultimap.of("key", "value"),
|
||||
"newkey", URI.create("http://localhost/pow") });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/pow");
|
||||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||
assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(),
|
||||
ReturnStringIf200.class);
|
||||
AddEntryIntoMultiMap.class);
|
||||
}
|
||||
|
||||
JaxrsAnnotationProcessor<PCSBlobStore> processor;
|
||||
|
@ -406,6 +419,9 @@ public class PCSBlobStoreTest {
|
|||
URI.create("http://localhost:8080"));
|
||||
bind(URI.class).annotatedWith(RootContainer.class).toInstance(
|
||||
URI.create("http://localhost:8080/root"));
|
||||
bind(URI.class).annotatedWith(WebDAV.class).toInstance(
|
||||
URI.create("http://localhost:8080/webdav"));
|
||||
bind(PCSConnection.class).to(StubPCSConnection.class).asEagerSingleton();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -414,12 +430,13 @@ public class PCSBlobStoreTest {
|
|||
public PCSUtil getPCSUtil() {
|
||||
return new PCSUtil() {
|
||||
|
||||
public String get(URI resource) {
|
||||
public Future<Void> put(URI resource, String value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean put(URI resource, String value) {
|
||||
return true;
|
||||
public Future<Void> addEntryToMultiMap(Multimap<String, String> map,
|
||||
String key, URI value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -102,14 +102,14 @@ public class PCSConnectionLiveTest {
|
|||
public void testObjectOperations() throws Exception {
|
||||
String containerName = containerPrefix + ".testObjectOperations";
|
||||
String data = "Here is my data";
|
||||
|
||||
|
||||
URI container = connection.createContainer(containerName).get(10, TimeUnit.SECONDS);
|
||||
|
||||
// Test PUT with string data, ETag hash, and a piece of metadata
|
||||
PCSFile object = new PCSFile("object");
|
||||
object.setData(data);
|
||||
object.setContentLength(data.length());
|
||||
URI objectURI = connection.uploadFile(container, object).get(10, TimeUnit.SECONDS);
|
||||
URI objectURI = connection.uploadFile(container, object).get(30, TimeUnit.SECONDS);
|
||||
|
||||
try {
|
||||
connection.downloadFile(UriBuilder.fromUri(objectURI).path("sad").build()).get(10,
|
||||
|
|
|
@ -33,6 +33,7 @@ import java.net.URI;
|
|||
import java.util.Collections;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
|
@ -58,6 +59,7 @@ import org.jclouds.util.Utils;
|
|||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -141,6 +143,23 @@ public class PCSConnectionTest {
|
|||
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||
}
|
||||
|
||||
public void testListContainersURI() throws SecurityException, NoSuchMethodException {
|
||||
Method method = PCSConnection.class.getMethod("listContainers", URI.class);
|
||||
|
||||
HttpRequest httpMethod = processor.createRequest(method, new Object[] { URI
|
||||
.create("http://localhost/mycontainer") });
|
||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||
assertEquals(httpMethod.getEndpoint().getPath(), "/mycontainer/contents");
|
||||
assertEquals(httpMethod.getEndpoint().getQuery(), null);
|
||||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||
assertEquals(httpMethod.getHeaders().size(), 1);
|
||||
assertEquals(httpMethod.getHeaders().get("X-Cloud-Depth"), Collections.singletonList("2"));
|
||||
assertEquals(processor.createResponseParser(method, httpMethod, null).getClass(),
|
||||
ParseSax.class);
|
||||
// TODO check generic type of response parser
|
||||
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||
}
|
||||
|
||||
public void testUploadFile() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = PCSConnection.class.getMethod("uploadFile", URI.class, PCSFile.class);
|
||||
|
||||
|
@ -214,12 +233,13 @@ public class PCSConnectionTest {
|
|||
public PCSUtil getPCSUtil() {
|
||||
return new PCSUtil() {
|
||||
|
||||
public String get(URI resource) {
|
||||
public Future<Void> put(URI resource, String value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean put(URI resource, String value) {
|
||||
return true;
|
||||
public Future<Void> addEntryToMultiMap(Multimap<String, String> map,
|
||||
String key, URI value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.jclouds.mezeo.pcs2.PCSConnection;
|
|||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||
import org.jclouds.mezeo.pcs2.endpoints.RootContainer;
|
||||
import org.jclouds.mezeo.pcs2.internal.StubPCSConnection;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
|
@ -58,6 +59,7 @@ public class StubPCSBlobStoreModule extends AbstractModule {
|
|||
}).asEagerSingleton();
|
||||
bind(PCSConnection.class).to(StubPCSConnection.class).asEagerSingleton();
|
||||
bind(URI.class).annotatedWith(PCS.class).toInstance(URI.create("https://localhost/pcsblob"));
|
||||
bind(URI.class).annotatedWith(RootContainer.class).toInstance(
|
||||
URI.create("http://localhost/root"));
|
||||
}
|
||||
|
||||
}
|
|
@ -31,6 +31,7 @@ import static org.easymock.classextension.EasyMock.verify;
|
|||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.ws.rs.ext.RuntimeDelegate;
|
||||
|
||||
|
@ -55,20 +56,22 @@ public class AddMetadataAndParseResourceIdIntoBytesTest {
|
|||
}
|
||||
HttpResponse response = new HttpResponse();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
PCSUtil createPCSUtil() {
|
||||
PCSUtil connection = createMock(PCSUtil.class);
|
||||
final Future<Void> voidF = createMock(Future.class);
|
||||
expect(
|
||||
connection
|
||||
.put(
|
||||
eq(URI
|
||||
.create("http://localhost/contents/7F143552-AAF5-11DE-BBB0-0BC388ED913B/metadata/foo")),
|
||||
eq("bar"))).andReturn(true);
|
||||
eq("bar"))).andReturn(voidF);
|
||||
expect(
|
||||
connection
|
||||
.put(
|
||||
eq(URI
|
||||
.create("http://localhost/contents/7F143552-AAF5-11DE-BBB0-0BC388ED913B/metadata/biz")),
|
||||
eq("baz"))).andReturn(true);
|
||||
eq("baz"))).andReturn(voidF);
|
||||
replay(connection);
|
||||
return connection;
|
||||
}
|
||||
|
|
|
@ -23,14 +23,21 @@
|
|||
*/
|
||||
package org.jclouds.mezeo.pcs2.functions;
|
||||
|
||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.mezeo.pcs2.PCSConnection;
|
||||
import org.jclouds.mezeo.pcs2.domain.ContainerMetadata;
|
||||
import org.jclouds.mezeo.pcs2.domain.FileMetadata;
|
||||
import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -44,25 +51,104 @@ import com.google.common.collect.ImmutableSortedSet;
|
|||
@Test(groups = "unit", testName = "pcs2.FindIdInContainerList")
|
||||
public class FindIdInContainerListTest {
|
||||
private DateService dateService = new DateService();
|
||||
private final PCSConnection connection = new PCSConnection() {
|
||||
|
||||
private final ImmutableSortedSet<ContainerMetadata> OF = ImmutableSortedSet
|
||||
.of(new ContainerMetadata(
|
||||
"test1",
|
||||
URI
|
||||
.create("https://pcsbeta.mezeo.net/v2/containers/7F143552-AAF5-11DE-BBB0-0BC388ED913B"),
|
||||
dateService.fromSeconds(1254008225), dateService.fromSeconds(1254008226),
|
||||
dateService.fromSeconds(1254008227), "adrian@jclouds.org", true, false, 1,
|
||||
1024));
|
||||
public Future<URI> createContainer(String container) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Future<URI> createContainer(URI parent, String container) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Future<Void> deleteContainer(URI container) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Future<Void> deleteFile(URI file) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Future<InputStream> downloadFile(URI file) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public SortedSet<ContainerMetadata> listContainers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Future<? extends SortedSet<ContainerMetadata>> listContainers(URI container) {
|
||||
if (container.equals(URI.create("https://localhost/root"))) {
|
||||
return createFuture(ImmutableSortedSet.of(new ContainerMetadata("apple", URI
|
||||
.create("https://localhost/containers/rootapple"), URI
|
||||
.create("https://localhost/root"), dateService.fromSeconds(1254008225),
|
||||
dateService.fromSeconds(1254008226), dateService.fromSeconds(1254008227),
|
||||
"adrian@jclouds.org", true, false, 1, 1024)));
|
||||
} else if (container.equals(URI.create("https://localhost/containers/rootapple"))) {
|
||||
return createFuture(ImmutableSortedSet.of(new ContainerMetadata("apple", URI
|
||||
.create("https://localhost/containers/appleapple"), URI
|
||||
.create("https://localhost/containers/rootapple"), dateService
|
||||
.fromSeconds(1254008225), dateService.fromSeconds(1254008226), dateService
|
||||
.fromSeconds(1254008227), "adrian@jclouds.org", true, false, 1, 1024)));
|
||||
} else {
|
||||
return createFuture(ImmutableSortedSet.<ContainerMetadata> of());
|
||||
}
|
||||
}
|
||||
|
||||
<T> Future<T> createFuture(final T data) {
|
||||
return new Future<T>() {
|
||||
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public T get() throws InterruptedException, ExecutionException {
|
||||
return data;
|
||||
}
|
||||
|
||||
public T get(long timeout, TimeUnit unit) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
return data;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public Future<? extends SortedSet<FileMetadata>> listFiles(URI container) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Future<URI> uploadFile(URI container, PCSFile object) {
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
FindIdInContainerList binder = new FindIdInContainerList(connection, URI
|
||||
.create("https://localhost/root"));
|
||||
|
||||
@Test(expectedExceptions = ContainerNotFoundException.class)
|
||||
public void testBad() {
|
||||
FindIdInContainerList binder = new FindIdInContainerList(createNiceMock(PCSConnection.class));
|
||||
binder.idForNameInListOrException("hello", OF);
|
||||
binder.apply("hello");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = ContainerNotFoundException.class)
|
||||
public void testBad2() {
|
||||
binder.apply("apple/hello");
|
||||
}
|
||||
|
||||
public void testGood() {
|
||||
FindIdInContainerList binder = new FindIdInContainerList(createNiceMock(PCSConnection.class));
|
||||
assertEquals(binder.idForNameInListOrException("test1", OF),
|
||||
"7F143552-AAF5-11DE-BBB0-0BC388ED913B");
|
||||
assertEquals(binder.apply("apple"), "rootapple");
|
||||
}
|
||||
|
||||
public void testSub() {
|
||||
assertEquals(binder.apply("apple/apple"), "appleapple");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public class PCSBlobStoreIntegrationTest extends
|
|||
assertEquals(metadata.getSize(), TEST_STRING.length());
|
||||
assertEquals(metadata.getUserMetadata().get("adrian"), Collections
|
||||
.singletonList("powderpuff"));
|
||||
// Content-MD5 not supported http://code.google.com/p/jclouds/issues/detail?id=105
|
||||
// Issue 105
|
||||
// assertEquals(metadata.getContentMD5(), HttpUtils.md5(TEST_STRING.getBytes()));
|
||||
}
|
||||
|
||||
|
@ -58,62 +58,64 @@ public class PCSBlobStoreIntegrationTest extends
|
|||
@Test(enabled = false)
|
||||
public void testGetIfMatch() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
// etag not supported http://code.google.com/p/jclouds/issues/detail?id=105
|
||||
// Issue 105
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testGetIfModifiedSince() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
// unsupported
|
||||
// Issue 105
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testGetIfNoneMatch() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
// etag not supported http://code.google.com/p/jclouds/issues/detail?id=105
|
||||
// Issue 105
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testGetIfUnmodifiedSince() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
// unsupported
|
||||
// Issue 105
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testGetRange() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
// unsupported http://code.google.com/p/jclouds/issues/detail?id=106
|
||||
// Issue 106, Mezeo defect 2644
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testGetStartAt() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
// unsupported http://code.google.com/p/jclouds/issues/detail?id=106
|
||||
// Issue 106, Mezeo defect 2644
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testGetTail() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
// unsupported http://code.google.com/p/jclouds/issues/detail?id=106
|
||||
// Issue 106, Mezeo defect 2644
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testGetTwoRanges() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
// unsupported http://code.google.com/p/jclouds/issues/detail?id=106
|
||||
// Issue 106, Mezeo defect 2644
|
||||
}
|
||||
|
||||
@DataProvider(name = "delete")
|
||||
@Override
|
||||
public Object[][] createData() {
|
||||
return new Object[][] { { "normal" } };
|
||||
// normal constraints: The characters \ / : * ? " < > and | cannot be used in names.
|
||||
public Object[][] createData() {// unicode Issue 110, Mezeo defect: 2675
|
||||
// slashes are supported, as they are a part of filepaths which we use nested container to
|
||||
// create.
|
||||
return new Object[][] { { "normal" }, { "sp ace" }, { "path/foo" } };
|
||||
}
|
||||
|
||||
}
|
|
@ -48,7 +48,7 @@ public class PCSTestInitializer extends
|
|||
@Override
|
||||
protected PCSContext createLiveContext(Module configurationModule, String url, String app,
|
||||
String account, String key) {
|
||||
return new PCSContextBuilder(URI.create(url), account, key).relaxSSLHostname().withModules(
|
||||
return new PCSContextBuilder(URI.create(url), account, key).relaxSSLHostname().withSaxDebug().withModules(
|
||||
configurationModule, new Log4JLoggingModule()).buildContext();
|
||||
}
|
||||
|
||||
|
|
|
@ -41,31 +41,48 @@ import org.jclouds.mezeo.pcs2.domain.PCSFile;
|
|||
*/
|
||||
public class StubPCSConnection implements PCSConnection {
|
||||
|
||||
public Future<URI> createContainer(String container) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
}
|
||||
|
||||
public Future<URI> createContainer(URI parent, String container) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
}
|
||||
|
||||
public Future<Void> deleteContainer(URI container) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
}
|
||||
|
||||
public Future<Void> deleteFile(URI file) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
}
|
||||
|
||||
public Future<InputStream> downloadFile(URI file) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Future<? extends SortedSet<FileMetadata>> listFiles(URI container) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Future<URI> uploadFile(URI container, PCSFile object) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Future<URI> createContainer(String container) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public SortedSet<ContainerMetadata> listContainers() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
}
|
||||
|
||||
public Future<? extends SortedSet<ContainerMetadata>> listContainers(URI container) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
}
|
||||
|
||||
public Future<? extends SortedSet<FileMetadata>> listFiles(URI container) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
}
|
||||
|
||||
public Future<URI> uploadFile(URI container, PCSFile object) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.net.URI;
|
||||
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.mezeo.pcs2.functions.Key;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
|
@ -44,4 +45,17 @@ public class PCSUtilsTest {
|
|||
.create("http://localhost/contents/7F143552-AAF5-11DE-BBB0-0BC388ED913B"));
|
||||
assertEquals(eTag, expected);
|
||||
}
|
||||
|
||||
public void testParseKey() {
|
||||
Key key = PCSUtils.parseKey(new Key("container", "key"));
|
||||
assertEquals(key.getContainer(), "container");
|
||||
assertEquals(key.getKey(), "key");
|
||||
key = PCSUtils.parseKey(new Key("container", "container/key"));
|
||||
assertEquals(key.getContainer(), "container/container");
|
||||
assertEquals(key.getKey(), "key");
|
||||
key = PCSUtils.parseKey(new Key("container", "/container/key"));
|
||||
assertEquals(key.getContainer(), "container/container");
|
||||
assertEquals(key.getKey(), "key");
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,8 @@ public class FileListToContainerMetadataListHandlerTest extends BaseHandlerTest
|
|||
"test1",
|
||||
URI
|
||||
.create("https://pcsbeta.mezeo.net/v2/containers/7F143552-AAF5-11DE-BBB0-0BC388ED913B"),
|
||||
URI
|
||||
.create("https://pcsbeta.mezeo.net/v2/containers/0B5C8F50-8E72-11DE-A1D4-D73479DA6257"),
|
||||
dateService.fromSeconds(1254008225), dateService.fromSeconds(1254008226),
|
||||
dateService.fromSeconds(1254008227), "adrian@jclouds.org", true, false, 1,
|
||||
1024));
|
||||
|
|
|
@ -23,14 +23,12 @@
|
|||
*/
|
||||
package org.jclouds.mezeo.pcs2.xml;
|
||||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
@ -42,6 +40,7 @@ import org.jclouds.util.DateService;
|
|||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
|
@ -54,7 +53,6 @@ import com.google.inject.Provides;
|
|||
public class FileMetadataHandlerTest extends BaseHandlerTest {
|
||||
|
||||
private DateService dateService;
|
||||
private PCSUtil util;
|
||||
|
||||
@BeforeTest
|
||||
@Override
|
||||
|
@ -66,19 +64,23 @@ public class FileMetadataHandlerTest extends BaseHandlerTest {
|
|||
protected void configure() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@SuppressWarnings( { "unused", "unchecked" })
|
||||
@Singleton
|
||||
@Provides
|
||||
PCSUtil provideUtil() {
|
||||
util = createMock(PCSUtil.class);
|
||||
// Note that we should convert uppercase to lowercase!
|
||||
expect(
|
||||
util
|
||||
.get(URI
|
||||
.create("https://pcsbeta.mezeo.net/v2/files/9E4C5AFA-A98B-11DE-8B4C-C3884B4A2DA3/metadata/Foo")))
|
||||
.andReturn("bar");
|
||||
replay(util);
|
||||
return util;
|
||||
final Future<Void> voidF = createMock(Future.class);
|
||||
return new PCSUtil() {
|
||||
public Future<Void> addEntryToMultiMap(Multimap<String, String> map, String key,
|
||||
URI value) {
|
||||
map.put(key.toLowerCase(), "bar");
|
||||
return voidF;
|
||||
}
|
||||
|
||||
public Future<Void> put(URI resource, String value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -96,10 +98,8 @@ public class FileMetadataHandlerTest extends BaseHandlerTest {
|
|||
MediaType.TEXT_PLAIN, false);
|
||||
// Note that we should convert uppercase to lowercase, since most clouds do anyway
|
||||
expects.getUserMetadata().put("foo", "bar");
|
||||
|
||||
FileMetadata result = (FileMetadata) factory.create(
|
||||
injector.getInstance(FileMetadataHandler.class)).parse(is);
|
||||
verify(util);
|
||||
|
||||
assertEquals(result, expects);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,11 @@
|
|||
<bytes>1024</bytes>
|
||||
<contents
|
||||
xlink:href="https://pcsbeta.mezeo.net/v2/containers/7F143552-AAF5-11DE-BBB0-0BC388ED913B/contents"
|
||||
xlink:type="simple" count="0" start="0" total="0" />
|
||||
xlink:type="simple" count="0" start="0" total="0">
|
||||
<container
|
||||
xlink:href="https://eval.mezeo.net/v2/containers/D3256E66-B29F-11DE-9597-BF70124CE977"
|
||||
xlink:type="simple" />
|
||||
</contents>
|
||||
<tags
|
||||
xlink:href="https://pcsbeta.mezeo.net/v2/containers/7F143552-AAF5-11DE-BBB0-0BC388ED913B/tags"
|
||||
xlink:type="simple" />
|
||||
|
|
Loading…
Reference in New Issue