Issue 128: added initial vfs module and fixed dependent bugs

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2374 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-12-07 07:09:57 +00:00
parent 8bbbd8c8ac
commit 9e340f286e
180 changed files with 5872 additions and 233 deletions

View File

@ -1,2 +1,25 @@
====
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.
====================================================================
====
thirdparty module is code we are temporarily storing as there is no maven module for it (or the code we use from it). thirdparty module is code we are temporarily storing as there is no maven module for it (or the code we use from it).
Please publish to maven repos manually as needed. Please publish to maven repos manually as needed.

View File

@ -111,6 +111,17 @@ public class AtmosAsyncBlobStore extends BaseAtmosBlobStore implements AsyncBlob
}); });
} }
public Future<Void> createDirectory(String container, String directory) {
return wrapFuture(async.createDirectory(container + "/" + directory),
new Function<URI, Void>() {
public Void apply(URI from) {
return null;// no etag
}
});
}
public Future<Void> deleteContainer(final String container) { public Future<Void> deleteContainer(final String container) {
return service.submit(new Callable<Void>() { return service.submit(new Callable<Void>() {
@ -130,10 +141,14 @@ public class AtmosAsyncBlobStore extends BaseAtmosBlobStore implements AsyncBlob
}); });
} }
public Future<Boolean> exists(String container) { public Future<Boolean> containerExists(String container) {
return async.pathExists(container); return async.pathExists(container);
} }
public Future<Boolean> directoryExists(String container, String directory) {
return async.pathExists(container + "/" + directory);
}
public Future<Blob> getBlob(String container, String key, public Future<Blob> getBlob(String container, String key,
org.jclouds.blobstore.options.GetOptions... optionsList) { org.jclouds.blobstore.options.GetOptions... optionsList) {
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList); GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
@ -151,8 +166,8 @@ public class AtmosAsyncBlobStore extends BaseAtmosBlobStore implements AsyncBlob
if (optionsList[0].isRecursive()) { if (optionsList[0].isRecursive()) {
throw new UnsupportedOperationException("recursive not currently supported in emcsaas"); throw new UnsupportedOperationException("recursive not currently supported in emcsaas");
} }
if (optionsList[0].getPath() != null) { if (optionsList[0].getDir() != null) {
container = container + "/" + optionsList[0].getPath(); container = container + "/" + optionsList[0].getDir();
} }
} }
ListOptions nativeOptions = container2ContainerListOptions.apply(optionsList); ListOptions nativeOptions = container2ContainerListOptions.apply(optionsList);

View File

@ -77,7 +77,6 @@ public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
} }
public void clearContainer(final String container) { public void clearContainer(final String container) {
clearContainerStrategy.execute(container, recursive()); clearContainerStrategy.execute(container, recursive());
} }
@ -86,6 +85,10 @@ public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
return true;// no etag return true;// no etag
} }
public void createDirectory(String container, String directory) {
sync.createDirectory(container + "/" + directory);
}
public void deleteContainer(final String container) { public void deleteContainer(final String container) {
clearContainerStrategy.execute(container, recursive()); clearContainerStrategy.execute(container, recursive());
deleteAndEnsurePathGone(container); deleteAndEnsurePathGone(container);
@ -106,10 +109,14 @@ public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
} }
} }
public boolean exists(String container) { public boolean containerExists(String container) {
return sync.pathExists(container); return sync.pathExists(container);
} }
public boolean directoryExists(String container, String directory) {
return sync.pathExists(container + "/" + directory);
}
public Blob getBlob(String container, String key, public Blob getBlob(String container, String key,
org.jclouds.blobstore.options.GetOptions... optionsList) { org.jclouds.blobstore.options.GetOptions... optionsList) {
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList); GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
@ -126,8 +133,8 @@ public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
if (optionsList[0].isRecursive()) { if (optionsList[0].isRecursive()) {
throw new UnsupportedOperationException("recursive not currently supported in emcsaas"); throw new UnsupportedOperationException("recursive not currently supported in emcsaas");
} }
if (optionsList[0].getPath() != null) { if (optionsList[0].getDir() != null) {
container = container + "/" + optionsList[0].getPath(); container = container + "/" + optionsList[0].getDir();
} }
} }
ListOptions nativeOptions = container2ContainerListOptions.apply(optionsList); ListOptions nativeOptions = container2ContainerListOptions.apply(optionsList);

View File

@ -118,8 +118,8 @@ public class RecursiveRemove implements ClearListStrategy, ClearContainerStrateg
public void execute(final String containerName, ListContainerOptions options) { public void execute(final String containerName, ListContainerOptions options) {
String path = containerName; String path = containerName;
if (options.getPath() != null) if (options.getDir() != null)
path += "/" + options.getPath(); path += "/" + options.getDir();
Set<Future<Void>> deletes = Sets.newHashSet(); Set<Future<Void>> deletes = Sets.newHashSet();
try { try {
for (DirectoryEntry md : async.listDirectory(path).get(requestTimeoutMilliseconds, for (DirectoryEntry md : async.listDirectory(path).get(requestTimeoutMilliseconds,

View File

@ -197,7 +197,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient {
container = directoryName.substring(0, directoryName.indexOf('/')); container = directoryName.substring(0, directoryName.indexOf('/'));
String path = directoryName.substring(directoryName.indexOf('/') + 1); String path = directoryName.substring(directoryName.indexOf('/') + 1);
if (!path.equals("")) if (!path.equals(""))
options.underPath(path); options.inDirectory(path);
} }
return wrapFuture(blobStore.list(container, options), resource2ObjectList); return wrapFuture(blobStore.list(container, options), resource2ObjectList);
} }
@ -208,7 +208,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient {
public Future<Boolean> pathExists(final String path) { public Future<Boolean> pathExists(final String path) {
if (path.indexOf('/') == -1 || (path.endsWith("/"))) if (path.indexOf('/') == -1 || (path.endsWith("/")))
return blobStore.exists(path); return blobStore.containerExists(path);
else { else {
return new FutureBase<Boolean>() { return new FutureBase<Boolean>() {
public Boolean get() throws InterruptedException, ExecutionException { public Boolean get() throws InterruptedException, ExecutionException {

View File

@ -1,3 +1,26 @@
====
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.
====================================================================
====
POST POST
application/octet-stream application/octet-stream

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.binders; package org.jclouds.aws.ec2.binders;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.binders; package org.jclouds.aws.ec2.binders;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.binders; package org.jclouds.aws.ec2.binders;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.binders; package org.jclouds.aws.ec2.binders;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.binders; package org.jclouds.aws.ec2.binders;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;
import org.jclouds.aws.ec2.EC2AsyncClient; import org.jclouds.aws.ec2.EC2AsyncClient;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;
import java.util.SortedSet; import java.util.SortedSet;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;
import java.util.SortedSet; import java.util.SortedSet;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.domain; package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.functions; package org.jclouds.aws.ec2.functions;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.options; package org.jclouds.aws.ec2.options;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.options; package org.jclouds.aws.ec2.options;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com> * Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
* *
* ==================================================================== * ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.util; package org.jclouds.aws.ec2.util;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com> * Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
* *
* ==================================================================== * ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com> * Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
* *
* ==================================================================== * ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com> * Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
* *
* ==================================================================== * ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one

View File

@ -11,7 +11,7 @@
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http: * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an

View File

@ -11,7 +11,7 @@
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http: * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an

View File

@ -11,7 +11,7 @@
* "License"); you may not use this file except in compliance * "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at * with the License. You may obtain a copy of the License at
* *
* http: * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an

View File

@ -31,6 +31,8 @@ import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_METADATA_PREF
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_RETRY; import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_RETRY;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SESSIONINTERVAL; import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SESSIONINTERVAL;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_TIMEOUT; import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_TIMEOUT;
import static org.jclouds.blobstore.reference.BlobStoreConstants.DIRECTORY_SUFFIX_FOLDER;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX;
import java.net.URI; import java.net.URI;
import java.util.Properties; import java.util.Properties;
@ -50,6 +52,7 @@ public class S3PropertiesBuilder extends HttpPropertiesBuilder {
properties.setProperty(PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com"); properties.setProperty(PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com");
properties.setProperty(PROPERTY_S3_METADATA_PREFIX, "x-amz-meta-"); properties.setProperty(PROPERTY_S3_METADATA_PREFIX, "x-amz-meta-");
properties.setProperty(PROPERTY_S3_SESSIONINTERVAL, "60"); properties.setProperty(PROPERTY_S3_SESSIONINTERVAL, "60");
properties.setProperty(PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX, DIRECTORY_SUFFIX_FOLDER);
return properties; return properties;
} }

View File

@ -48,6 +48,7 @@ import org.jclouds.aws.s3.domain.ObjectMetadata;
import org.jclouds.aws.s3.domain.S3Object; import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.options.ListBucketOptions; import org.jclouds.aws.s3.options.ListBucketOptions;
import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse; import org.jclouds.blobstore.domain.ListContainerResponse;
@ -57,6 +58,8 @@ import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.domain.internal.ListResponseImpl; import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy; import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.blobstore.strategy.GetDirectoryStrategy;
import org.jclouds.blobstore.strategy.MkdirStrategy;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
@ -71,11 +74,13 @@ public class S3AsyncBlobStore extends BaseS3BlobStore implements AsyncBlobStore
ObjectToBlobMetadata object2BlobMd, ObjectToBlob object2Blob, BlobToObject blob2Object, ObjectToBlobMetadata object2BlobMd, ObjectToBlob object2Blob, BlobToObject blob2Object,
ContainerToBucketListOptions container2BucketListOptions, ContainerToBucketListOptions container2BucketListOptions,
BlobToObjectGetOptions blob2ObjectGetOptions, BlobToObjectGetOptions blob2ObjectGetOptions,
GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy,
BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList, BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList,
ExecutorService service) { ExecutorService service) {
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd, super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2BucketListOptions, blob2ObjectGetOptions, object2Blob, blob2Object, container2BucketListOptions, blob2ObjectGetOptions,
bucket2ResourceMd, bucket2ResourceList, service); getDirectoryStrategy, mkdirStrategy, bucket2ResourceMd, bucket2ResourceList,
service);
} }
/** /**
@ -104,10 +109,6 @@ public class S3AsyncBlobStore extends BaseS3BlobStore implements AsyncBlobStore
}); });
} }
public Future<Boolean> createContainer(String container) {
return async.putBucketIfNotExists(container);
}
public Future<Void> deleteContainer(final String container) { public Future<Void> deleteContainer(final String container) {
return service.submit(new Callable<Void>() { return service.submit(new Callable<Void>() {
@ -120,10 +121,40 @@ public class S3AsyncBlobStore extends BaseS3BlobStore implements AsyncBlobStore
}); });
} }
public Future<Boolean> exists(String container) { public Future<Boolean> createContainer(String container) {
return async.putBucketIfNotExists(container);
}
public Future<Boolean> containerExists(String container) {
return async.bucketExists(container); return async.bucketExists(container);
} }
public Future<Void> createDirectory(final String container, final String directory) {
return service.submit(new Callable<Void>() {
public Void call() throws Exception {
mkdirStrategy.execute(S3AsyncBlobStore.this, container, directory);
return null;
}
});
}
public Future<Boolean> directoryExists(final String container, final String directory) {
return service.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
try {
getDirectoryStrategy.execute(S3AsyncBlobStore.this, container, directory);
return true;
} catch (KeyNotFoundException e) {
return false;
}
}
});
}
public Future<Blob> getBlob(String container, String key, public Future<Blob> getBlob(String container, String key,
org.jclouds.blobstore.options.GetOptions... optionsList) { org.jclouds.blobstore.options.GetOptions... optionsList) {
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList); GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);

View File

@ -43,6 +43,7 @@ import org.jclouds.aws.s3.blobstore.internal.BaseS3BlobStore;
import org.jclouds.aws.s3.domain.BucketMetadata; import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.options.ListBucketOptions; import org.jclouds.aws.s3.options.ListBucketOptions;
import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse; import org.jclouds.blobstore.domain.ListContainerResponse;
@ -52,6 +53,8 @@ import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.domain.internal.ListResponseImpl; import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy; import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.blobstore.strategy.GetDirectoryStrategy;
import org.jclouds.blobstore.strategy.MkdirStrategy;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
@ -59,18 +62,22 @@ import com.google.common.base.Function;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
public class S3BlobStore extends BaseS3BlobStore implements BlobStore { public class S3BlobStore extends BaseS3BlobStore implements BlobStore {
private final S3AsyncBlobStore aBlobStore;
@Inject @Inject
public S3BlobStore(S3AsyncClient async, S3Client sync, Factory blobFactory, public S3BlobStore(S3AsyncBlobStore aBlobStore, S3AsyncClient async, S3Client sync,
LoggerFactory logFactory, ClearListStrategy clearContainerStrategy, Factory blobFactory, LoggerFactory logFactory,
ObjectToBlobMetadata object2BlobMd, ObjectToBlob object2Blob, BlobToObject blob2Object, ClearListStrategy clearContainerStrategy, ObjectToBlobMetadata object2BlobMd,
ObjectToBlob object2Blob, BlobToObject blob2Object,
ContainerToBucketListOptions container2BucketListOptions, ContainerToBucketListOptions container2BucketListOptions,
BlobToObjectGetOptions blob2ObjectGetOptions, BlobToObjectGetOptions blob2ObjectGetOptions,
GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy,
BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList, BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList,
ExecutorService service) { ExecutorService service) {
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd, super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2BucketListOptions, blob2ObjectGetOptions, object2Blob, blob2Object, container2BucketListOptions, blob2ObjectGetOptions,
bucket2ResourceMd, bucket2ResourceList, service); getDirectoryStrategy, mkdirStrategy, bucket2ResourceMd, bucket2ResourceList, service);
this.aBlobStore = aBlobStore;
} }
/** /**
@ -84,6 +91,10 @@ public class S3BlobStore extends BaseS3BlobStore implements BlobStore {
clearContainerStrategy.execute(container, recursive()); clearContainerStrategy.execute(container, recursive());
} }
public boolean containerExists(String container) {
return sync.bucketExists(container);
}
public boolean createContainer(String container) { public boolean createContainer(String container) {
return sync.putBucketIfNotExists(container); return sync.putBucketIfNotExists(container);
} }
@ -93,8 +104,17 @@ public class S3BlobStore extends BaseS3BlobStore implements BlobStore {
sync.deleteBucketIfEmpty(container); sync.deleteBucketIfEmpty(container);
} }
public boolean exists(String container) { public boolean directoryExists(String containerName, String directory) {
return sync.bucketExists(container); try {
getDirectoryStrategy.execute(aBlobStore, containerName, directory);
return true;
} catch (KeyNotFoundException e) {
return false;
}
}
public void createDirectory(String containerName, String directory) {
mkdirStrategy.execute(aBlobStore, containerName, directory);
} }
public Blob getBlob(String container, String key, public Blob getBlob(String container, String key,

View File

@ -52,7 +52,12 @@ public class BlobToObjectGetOptions implements
} }
for (String range : from[0].getRanges()) { for (String range : from[0].getRanges()) {
String[] firstLast = range.split("\\-"); String[] firstLast = range.split("\\-");
if (firstLast.length == 2)
httpOptions.range(Long.parseLong(firstLast[0]), Long.parseLong(firstLast[1])); httpOptions.range(Long.parseLong(firstLast[0]), Long.parseLong(firstLast[1]));
else if (range.startsWith("-"))
httpOptions.tail(Long.parseLong(firstLast[0]));
else
httpOptions.startAt(Long.parseLong(firstLast[0]));
} }
} }
return httpOptions; return httpOptions;

View File

@ -50,7 +50,7 @@ public class BucketToContainerListOptions implements Function<ListBucketOptions[
options.maxResults(optionsList[0].getMaxResults()); options.maxResults(optionsList[0].getMaxResults());
} }
if (optionsList[0].getPrefix() != null) { if (optionsList[0].getPrefix() != null) {
options.underPath(optionsList[0].getPrefix()); options.inDirectory(optionsList[0].getPrefix());
} }
} }
return options; return options;

View File

@ -34,15 +34,19 @@ import com.google.common.base.Function;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class ContainerToBucketListOptions implements Function<ListContainerOptions[], ListBucketOptions> { public class ContainerToBucketListOptions implements
Function<ListContainerOptions[], ListBucketOptions> {
public ListBucketOptions apply(ListContainerOptions[] optionsList) { public ListBucketOptions apply(ListContainerOptions[] optionsList) {
ListBucketOptions httpOptions = new ListBucketOptions(); ListBucketOptions httpOptions = new ListBucketOptions();
if (optionsList.length != 0) { if (optionsList.length != 0) {
if (!optionsList[0].isRecursive()) { if (!optionsList[0].isRecursive()) {
httpOptions.delimiter("/"); httpOptions.delimiter("/");
} }
if (optionsList[0].getPath() != null) { if (optionsList[0].getDir() != null) {// TODO unit test
httpOptions.withPrefix(optionsList[0].getPath()); String path = optionsList[0].getDir();
if (!path.endsWith("/"))
path = path + "/";
httpOptions.withPrefix(path);
} }
if (optionsList[0].getMarker() != null) { if (optionsList[0].getMarker() != null) {
httpOptions.afterMarker(optionsList[0].getMarker()); httpOptions.afterMarker(optionsList[0].getMarker());

View File

@ -23,12 +23,14 @@
*/ */
package org.jclouds.aws.s3.blobstore.functions; package org.jclouds.aws.s3.blobstore.functions;
import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.s3.domain.ObjectMetadata; import org.jclouds.aws.s3.domain.ObjectMetadata;
import org.jclouds.blobstore.domain.MutableBlobMetadata; import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceType; import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl; import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -37,6 +39,13 @@ import com.google.common.base.Function;
*/ */
@Singleton @Singleton
public class ObjectToBlobMetadata implements Function<ObjectMetadata, MutableBlobMetadata> { public class ObjectToBlobMetadata implements Function<ObjectMetadata, MutableBlobMetadata> {
private final IsDirectoryStrategy isDirectoryStrategy;
@Inject
public ObjectToBlobMetadata(IsDirectoryStrategy isDirectoryStrategy) {
this.isDirectoryStrategy = isDirectoryStrategy;
}
public MutableBlobMetadata apply(ObjectMetadata from) { public MutableBlobMetadata apply(ObjectMetadata from) {
MutableBlobMetadata to = new MutableBlobMetadataImpl(); MutableBlobMetadata to = new MutableBlobMetadataImpl();
to.setContentMD5(from.getContentMD5()); to.setContentMD5(from.getContentMD5());
@ -46,8 +55,9 @@ public class ObjectToBlobMetadata implements Function<ObjectMetadata, MutableBlo
to.setName(from.getKey()); to.setName(from.getKey());
to.setSize(from.getSize()); to.setSize(from.getSize());
to.setType(ResourceType.BLOB); to.setType(ResourceType.BLOB);
to.setLastModified(from.getLastModified());
to.setUserMetadata(from.getUserMetadata()); to.setUserMetadata(from.getUserMetadata());
if (from.getContentType() != null && from.getContentType().equals("application/directory")) { if (isDirectoryStrategy.execute(to)) {
to.setType(ResourceType.RELATIVE_PATH); to.setType(ResourceType.RELATIVE_PATH);
} }
return to; return to;

View File

@ -41,6 +41,8 @@ import org.jclouds.aws.s3.blobstore.functions.ObjectToBlob;
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlobMetadata; import org.jclouds.aws.s3.blobstore.functions.ObjectToBlobMetadata;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.strategy.ClearListStrategy; import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.blobstore.strategy.GetDirectoryStrategy;
import org.jclouds.blobstore.strategy.MkdirStrategy;
import org.jclouds.concurrent.FutureFunctionWrapper; import org.jclouds.concurrent.FutureFunctionWrapper;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
@ -60,6 +62,8 @@ public class BaseS3BlobStore {
protected final BucketToResourceMetadata bucket2ResourceMd; protected final BucketToResourceMetadata bucket2ResourceMd;
protected final BucketToResourceList bucket2ResourceList; protected final BucketToResourceList bucket2ResourceList;
protected final ExecutorService service; protected final ExecutorService service;
protected final GetDirectoryStrategy getDirectoryStrategy;
protected final MkdirStrategy mkdirStrategy;
@Inject @Inject
protected BaseS3BlobStore(S3AsyncClient async, S3Client sync, Blob.Factory blobFactory, protected BaseS3BlobStore(S3AsyncClient async, S3Client sync, Blob.Factory blobFactory,
@ -67,6 +71,7 @@ public class BaseS3BlobStore {
ObjectToBlobMetadata object2BlobMd, ObjectToBlob object2Blob, BlobToObject blob2Object, ObjectToBlobMetadata object2BlobMd, ObjectToBlob object2Blob, BlobToObject blob2Object,
ContainerToBucketListOptions container2BucketListOptions, ContainerToBucketListOptions container2BucketListOptions,
BlobToObjectGetOptions blob2ObjectGetOptions, BlobToObjectGetOptions blob2ObjectGetOptions,
GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy,
BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList, BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList,
ExecutorService service) { ExecutorService service) {
this.async = checkNotNull(async, "async"); this.async = checkNotNull(async, "async");
@ -80,6 +85,9 @@ public class BaseS3BlobStore {
this.container2BucketListOptions = checkNotNull(container2BucketListOptions, this.container2BucketListOptions = checkNotNull(container2BucketListOptions,
"container2BucketListOptions"); "container2BucketListOptions");
this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions"); this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
this.getDirectoryStrategy = checkNotNull(getDirectoryStrategy,
"getDirectoryStrategy");
this.mkdirStrategy = checkNotNull(mkdirStrategy, "mkdirStrategy");
this.bucket2ResourceMd = checkNotNull(bucket2ResourceMd, "bucket2ResourceMd"); this.bucket2ResourceMd = checkNotNull(bucket2ResourceMd, "bucket2ResourceMd");
this.bucket2ResourceList = checkNotNull(bucket2ResourceList, "bucket2ResourceList"); this.bucket2ResourceList = checkNotNull(bucket2ResourceList, "bucket2ResourceList");
this.service = checkNotNull(service, "service"); this.service = checkNotNull(service, "service");

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.util; package org.jclouds.aws.util;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.util; package org.jclouds.aws.util;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.config; package org.jclouds.aws.ec2.config;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.filters; package org.jclouds.aws.ec2.filters;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.options; package org.jclouds.aws.ec2.options;
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.executableBy; import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.executableBy;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.aws.ec2.options; package org.jclouds.aws.ec2.options;
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.asType; import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.asType;

View File

@ -59,7 +59,7 @@ public class BlobStoreContextToContainerResult implements Function<String, Conta
try { try {
try { try {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
context.getBlobStore().exists(from.getName()); context.getBlobStore().containerExists(from.getName());
status = ((System.currentTimeMillis() - start) + "ms"); status = ((System.currentTimeMillis() - start) + "ms");
} catch (ContainerNotFoundException ex) { } catch (ContainerNotFoundException ex) {
status = ("not found"); status = ("not found");

View File

@ -57,7 +57,7 @@ public abstract class BasePerformanceLiveTest extends
containerCount = 1; containerCount = 1;
} }
protected int timeoutSeconds = 15; protected int timeoutSeconds = 15;
protected int loopCount = 100; protected int loopCount = 1000;
protected ExecutorService exec; protected ExecutorService exec;
protected CompletionService<Boolean> completer; protected CompletionService<Boolean> completer;

View File

@ -47,6 +47,7 @@ import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties; import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
import org.jclouds.azure.storage.blob.options.ListBlobsOptions; import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse; import org.jclouds.blobstore.domain.ListContainerResponse;
@ -56,6 +57,8 @@ import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions; import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy; import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.blobstore.strategy.GetDirectoryStrategy;
import org.jclouds.blobstore.strategy.MkdirStrategy;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
@ -70,12 +73,13 @@ public class AzureAsyncBlobStore extends BaseAzureBlobStore implements AsyncBlob
ClearListStrategy clearContainerStrategy, BlobPropertiesToBlobMetadata object2BlobMd, ClearListStrategy clearContainerStrategy, BlobPropertiesToBlobMetadata object2BlobMd,
AzureBlobToBlob object2Blob, BlobToAzureBlob blob2Object, AzureBlobToBlob object2Blob, BlobToAzureBlob blob2Object,
ListOptionsToListBlobsOptions container2ContainerListOptions, ListOptionsToListBlobsOptions container2ContainerListOptions,
BlobToHttpGetOptions blob2ObjectGetOptions, BlobToHttpGetOptions blob2ObjectGetOptions, GetDirectoryStrategy getDirectoryStrategy,
ContainerToResourceMetadata container2ResourceMd, MkdirStrategy mkdirStrategy, ContainerToResourceMetadata container2ResourceMd,
ListBlobsResponseToResourceList container2ResourceList, ExecutorService service) { ListBlobsResponseToResourceList container2ResourceList, ExecutorService service) {
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd, super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions, object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions,
container2ResourceMd, container2ResourceList, service); getDirectoryStrategy, mkdirStrategy, container2ResourceMd, container2ResourceList,
service);
} }
/** /**
@ -113,7 +117,7 @@ public class AzureAsyncBlobStore extends BaseAzureBlobStore implements AsyncBlob
} }
public Future<Boolean> exists(String container) { public Future<Boolean> containerExists(String container) {
return async.containerExists(container); return async.containerExists(container);
} }
@ -151,4 +155,30 @@ public class AzureAsyncBlobStore extends BaseAzureBlobStore implements AsyncBlob
return async.deleteBlob(container, key); return async.deleteBlob(container, key);
} }
public Future<Void> createDirectory(final String container, final String directory) {
return service.submit(new Callable<Void>() {
public Void call() throws Exception {
mkdirStrategy.execute(AzureAsyncBlobStore.this, container, directory);
return null;
}
});
}
public Future<Boolean> directoryExists(final String container, final String directory) {
return service.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
try {
getDirectoryStrategy.execute(AzureAsyncBlobStore.this, container, directory);
return true;
} catch (KeyNotFoundException e) {
return false;
}
}
});
}
} }

View File

@ -42,6 +42,7 @@ import org.jclouds.azure.storage.blob.blobstore.internal.BaseAzureBlobStore;
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties; import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
import org.jclouds.azure.storage.blob.options.ListBlobsOptions; import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse; import org.jclouds.blobstore.domain.ListContainerResponse;
@ -52,6 +53,8 @@ import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions; import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy; import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.blobstore.strategy.GetDirectoryStrategy;
import org.jclouds.blobstore.strategy.MkdirStrategy;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
@ -59,19 +62,22 @@ import com.google.common.base.Function;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
public class AzureBlobStore extends BaseAzureBlobStore implements BlobStore { public class AzureBlobStore extends BaseAzureBlobStore implements BlobStore {
private final AzureAsyncBlobStore aBlobStore;
@Inject @Inject
public AzureBlobStore(AzureBlobAsyncClient async, AzureBlobClient sync, Factory blobFactory, public AzureBlobStore(AzureAsyncBlobStore aBlobStore, AzureBlobAsyncClient async,
LoggerFactory logFactory, ClearListStrategy clearContainerStrategy, AzureBlobClient sync, Factory blobFactory, LoggerFactory logFactory,
BlobPropertiesToBlobMetadata object2BlobMd, AzureBlobToBlob object2Blob, ClearListStrategy clearContainerStrategy, BlobPropertiesToBlobMetadata object2BlobMd,
BlobToAzureBlob blob2Object, AzureBlobToBlob object2Blob, BlobToAzureBlob blob2Object,
ListOptionsToListBlobsOptions container2ContainerListOptions, ListOptionsToListBlobsOptions container2ContainerListOptions,
BlobToHttpGetOptions blob2ObjectGetOptions, BlobToHttpGetOptions blob2ObjectGetOptions, GetDirectoryStrategy getDirectoryStrategy,
ContainerToResourceMetadata container2ResourceMd, MkdirStrategy mkdirStrategy, ContainerToResourceMetadata container2ResourceMd,
ListBlobsResponseToResourceList container2ResourceList, ExecutorService service) { ListBlobsResponseToResourceList container2ResourceList, ExecutorService service) {
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd, super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions, object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions,
container2ResourceMd, container2ResourceList, service); getDirectoryStrategy, mkdirStrategy, container2ResourceMd, container2ResourceList,
service);
this.aBlobStore = aBlobStore;
} }
/** /**
@ -93,7 +99,20 @@ public class AzureBlobStore extends BaseAzureBlobStore implements BlobStore {
sync.deleteContainer(container); sync.deleteContainer(container);
} }
public boolean exists(String container) { public boolean directoryExists(String containerName, String directory) {
try {
getDirectoryStrategy.execute(aBlobStore, containerName, directory);
return true;
} catch (KeyNotFoundException e) {
return false;
}
}
public void createDirectory(String containerName, String directory) {
mkdirStrategy.execute(aBlobStore, containerName, directory);
}
public boolean containerExists(String container) {
return sync.containerExists(container); return sync.containerExists(container);
} }

View File

@ -23,10 +23,12 @@
*/ */
package org.jclouds.azure.storage.blob.blobstore.functions; package org.jclouds.azure.storage.blob.blobstore.functions;
import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.azure.storage.blob.domain.BlobProperties; import org.jclouds.azure.storage.blob.domain.BlobProperties;
import org.jclouds.blobstore.domain.MutableBlobMetadata; import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
/** /**
* @author Adrian Cole * @author Adrian Cole
@ -34,6 +36,11 @@ import org.jclouds.blobstore.domain.MutableBlobMetadata;
@Singleton @Singleton
public class BlobPropertiesToBlobMetadata extends public class BlobPropertiesToBlobMetadata extends
ListableBlobPropertiesToBlobMetadata<BlobProperties> { ListableBlobPropertiesToBlobMetadata<BlobProperties> {
@Inject
public BlobPropertiesToBlobMetadata(IsDirectoryStrategy isDirectoryStrategy) {
super(isDirectoryStrategy);
}
@Override @Override
public MutableBlobMetadata apply(BlobProperties from) { public MutableBlobMetadata apply(BlobProperties from) {
MutableBlobMetadata to = super.apply(from); MutableBlobMetadata to = super.apply(from);

View File

@ -50,7 +50,7 @@ public class ListBlobsOptionsToListOptions implements Function<ListBlobsOptions[
options.maxResults(optionsList[0].getMaxResults()); options.maxResults(optionsList[0].getMaxResults());
} }
if (optionsList[0].getPrefix() != null) { if (optionsList[0].getPrefix() != null) {
options.underPath(optionsList[0].getPrefix()); options.inDirectory(optionsList[0].getPrefix());
} }
} }
return options; return options;

View File

@ -41,8 +41,8 @@ public class ListOptionsToListBlobsOptions implements Function<ListContainerOpti
if (!optionsList[0].isRecursive()) { if (!optionsList[0].isRecursive()) {
httpOptions.delimiter("/"); httpOptions.delimiter("/");
} }
if (optionsList[0].getPath() != null) { if (optionsList[0].getDir() != null) {
httpOptions.prefix(optionsList[0].getPath()); httpOptions.prefix(optionsList[0].getDir());
} }
if (optionsList[0].getMarker() != null) { if (optionsList[0].getMarker() != null) {
httpOptions.marker(optionsList[0].getMarker()); httpOptions.marker(optionsList[0].getMarker());

View File

@ -23,12 +23,14 @@
*/ */
package org.jclouds.azure.storage.blob.blobstore.functions; package org.jclouds.azure.storage.blob.blobstore.functions;
import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties; import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
import org.jclouds.blobstore.domain.MutableBlobMetadata; import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceType; import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl; import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -38,15 +40,23 @@ import com.google.common.base.Function;
@Singleton @Singleton
public class ListableBlobPropertiesToBlobMetadata<T extends ListableBlobProperties> implements public class ListableBlobPropertiesToBlobMetadata<T extends ListableBlobProperties> implements
Function<T, MutableBlobMetadata> { Function<T, MutableBlobMetadata> {
private final IsDirectoryStrategy isDirectoryStrategy;
@Inject
public ListableBlobPropertiesToBlobMetadata(IsDirectoryStrategy isDirectoryStrategy) {
this.isDirectoryStrategy = isDirectoryStrategy;
}
public MutableBlobMetadata apply(T from) { public MutableBlobMetadata apply(T from) {
MutableBlobMetadata to = new MutableBlobMetadataImpl(); MutableBlobMetadata to = new MutableBlobMetadataImpl();
if (from.getContentType() != null) if (from.getContentType() != null)
to.setContentType(from.getContentType()); to.setContentType(from.getContentType());
to.setETag(from.getETag()); to.setETag(from.getETag());
to.setLastModified(from.getLastModified());
to.setName(from.getName()); to.setName(from.getName());
to.setSize(from.getSize()); to.setSize(from.getSize());
to.setType(ResourceType.BLOB); to.setType(ResourceType.BLOB);
if (from.getContentType() != null && from.getContentType().equals("application/directory")) { if (isDirectoryStrategy.execute(to)) {
to.setType(ResourceType.RELATIVE_PATH); to.setType(ResourceType.RELATIVE_PATH);
} }
return to; return to;

View File

@ -41,6 +41,8 @@ import org.jclouds.azure.storage.blob.blobstore.functions.ListOptionsToListBlobs
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions; import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy; import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.blobstore.strategy.GetDirectoryStrategy;
import org.jclouds.blobstore.strategy.MkdirStrategy;
import org.jclouds.concurrent.FutureFunctionWrapper; import org.jclouds.concurrent.FutureFunctionWrapper;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
@ -60,6 +62,8 @@ public class BaseAzureBlobStore {
protected final ContainerToResourceMetadata container2ResourceMd; protected final ContainerToResourceMetadata container2ResourceMd;
protected final ListBlobsResponseToResourceList container2ResourceList; protected final ListBlobsResponseToResourceList container2ResourceList;
protected final ExecutorService service; protected final ExecutorService service;
protected final GetDirectoryStrategy getDirectoryStrategy;
protected final MkdirStrategy mkdirStrategy;
@Inject @Inject
protected BaseAzureBlobStore(AzureBlobAsyncClient async, AzureBlobClient sync, protected BaseAzureBlobStore(AzureBlobAsyncClient async, AzureBlobClient sync,
@ -68,6 +72,7 @@ public class BaseAzureBlobStore {
AzureBlobToBlob object2Blob, BlobToAzureBlob blob2Object, AzureBlobToBlob object2Blob, BlobToAzureBlob blob2Object,
ListOptionsToListBlobsOptions container2ContainerListOptions, ListOptionsToListBlobsOptions container2ContainerListOptions,
BlobToHttpGetOptions blob2ObjectGetOptions, BlobToHttpGetOptions blob2ObjectGetOptions,
GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy,
ContainerToResourceMetadata container2ResourceMd, ContainerToResourceMetadata container2ResourceMd,
ListBlobsResponseToResourceList container2ResourceList, ExecutorService service) { ListBlobsResponseToResourceList container2ResourceList, ExecutorService service) {
this.async = checkNotNull(async, "async"); this.async = checkNotNull(async, "async");
@ -81,6 +86,9 @@ public class BaseAzureBlobStore {
this.container2ContainerListOptions = checkNotNull(container2ContainerListOptions, this.container2ContainerListOptions = checkNotNull(container2ContainerListOptions,
"container2ContainerListOptions"); "container2ContainerListOptions");
this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions"); this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
this.getDirectoryStrategy = checkNotNull(getDirectoryStrategy,
"getDirectoryStrategy");
this.mkdirStrategy = checkNotNull(mkdirStrategy, "mkdirStrategy");
this.container2ResourceMd = checkNotNull(container2ResourceMd, "container2ResourceMd"); this.container2ResourceMd = checkNotNull(container2ResourceMd, "container2ResourceMd");
this.container2ResourceList = checkNotNull(container2ResourceList, "container2ResourceList"); this.container2ResourceList = checkNotNull(container2ResourceList, "container2ResourceList");
this.service = checkNotNull(service, "service"); this.service = checkNotNull(service, "service");

View File

@ -32,6 +32,7 @@ import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties; import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
import org.jclouds.azure.storage.blob.domain.internal.ListableBlobPropertiesImpl; import org.jclouds.azure.storage.blob.domain.internal.ListableBlobPropertiesImpl;
import org.jclouds.azure.storage.blob.domain.internal.TreeSetListBlobsResponse; import org.jclouds.azure.storage.blob.domain.internal.TreeSetListBlobsResponse;
import org.jclouds.blobstore.internal.LocationAndCredentials;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.DateService; import org.jclouds.util.DateService;
import org.joda.time.DateTime; import org.joda.time.DateTime;
@ -127,7 +128,7 @@ public class ContainerNameEnumerationResultsHandler extends
currentContentEncoding = null; currentContentEncoding = null;
currentContentLanguage = null; currentContentLanguage = null;
} else if (qName.equals("Url")) { } else if (qName.equals("Url")) {
currentUrl = URI.create(currentText.toString().trim()); currentUrl = LocationAndCredentials.parse(currentText.toString().trim()).uri;
} else if (qName.equals("LastModified")) { } else if (qName.equals("LastModified")) {
currentLastModified = dateParser.rfc822DateParse(currentText.toString().trim()); currentLastModified = dateParser.rfc822DateParse(currentText.toString().trim());
} else if (qName.equals("Etag")) { } else if (qName.equals("Etag")) {

View File

@ -29,6 +29,7 @@ import javax.inject.Inject;
import org.jclouds.azure.storage.AzureStorageResponseException; import org.jclouds.azure.storage.AzureStorageResponseException;
import org.jclouds.azure.storage.domain.AzureStorageError; import org.jclouds.azure.storage.domain.AzureStorageError;
import org.jclouds.azure.storage.util.AzureStorageUtils; import org.jclouds.azure.storage.util.AzureStorageUtils;
import org.jclouds.blobstore.ContainerNotFoundException;
import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
@ -64,7 +65,13 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler {
if (content.indexOf('<') >= 0) { if (content.indexOf('<') >= 0) {
AzureStorageError error = utils.parseAzureStorageErrorFromContent(command, AzureStorageError error = utils.parseAzureStorageErrorFromContent(command,
response, content); response, content);
command.setException(new AzureStorageResponseException(command, response, error)); AzureStorageResponseException ex = new AzureStorageResponseException(command,
response, error);
if (error.getCode().equals("ContainerNotFound")) {
command.setException(new ContainerNotFoundException(ex));
} else {
command.setException(ex);
}
} else { } else {
command.setException(new HttpResponseException(command, response, content)); command.setException(new HttpResponseException(command, response, content));
} }

View File

@ -1,76 +0,0 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.azure.storage.blob.config;
import static org.testng.Assert.assertEquals;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.AzureBlobClient;
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.internal.RestContextImpl;
import org.jclouds.util.Jsr330;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "azureblob.AzureBlobContextModuleTest")
public class AzureBlobContextModuleTest {
Injector createInjector() {
return Guice.createInjector(new AzureBlobStubClientModule(), new JDKLoggingModule(),
new AzureBlobContextModule() {
@Override
protected void configure() {
bindConstant().annotatedWith(
Jsr330.named(AzureBlobConstants.PROPERTY_AZURESTORAGE_ACCOUNT)).to(
"user");
bindConstant().annotatedWith(
Jsr330.named(AzureBlobConstants.PROPERTY_AZURESTORAGE_KEY)).to("key");
bindConstant().annotatedWith(
Jsr330.named(AzureBlobConstants.PROPERTY_AZUREBLOB_ENDPOINT)).to(
"http://localhost");
super.configure();
}
});
}
@Test
void testContextImpl() {
Injector injector = createInjector();
RestContext<AzureBlobAsyncClient, AzureBlobClient> handler = injector.getInstance(Key
.get(new TypeLiteral<RestContext<AzureBlobAsyncClient, AzureBlobClient>>() {
}));
assertEquals(handler.getClass(), RestContextImpl.class);
}
}

View File

@ -57,10 +57,14 @@ public interface AsyncBlobStore {
Future<? extends ListContainerResponse<? extends ResourceMetadata>> list(String container, Future<? extends ListContainerResponse<? extends ResourceMetadata>> list(String container,
ListContainerOptions... options); ListContainerOptions... options);
Future<Boolean> exists(String container); Future<Boolean> containerExists(String container);
Future<Boolean> directoryExists(String container, String directory);
Future<Boolean> createContainer(String container); Future<Boolean> createContainer(String container);
Future<Void> createDirectory(String container, String directory);
/** /**
* This will delete a container recursively. * This will delete a container recursively.
* *

View File

@ -55,10 +55,14 @@ public interface BlobStore {
ListContainerResponse<? extends ResourceMetadata> list(String container, ListContainerResponse<? extends ResourceMetadata> list(String container,
ListContainerOptions... options); ListContainerOptions... options);
boolean exists(String container); boolean containerExists(String container);
boolean directoryExists(String container, String directory);
boolean createContainer(String container); boolean createContainer(String container);
void createDirectory(String container, String directory);
/** /**
* This will delete a container recursively. * This will delete a container recursively.
* *

View File

@ -0,0 +1,74 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Properties;
import javax.inject.Inject;
import org.jclouds.http.HttpPropertiesBuilder;
import com.google.inject.Module;
public class BlobStoreContextFactory {
private final Properties properties;
@Inject
public BlobStoreContextFactory(Properties properties) {
this.properties = properties;
}
@SuppressWarnings("unchecked")
public BlobStoreContext<?, ?> createContext(URI blobStore, String account, String key,
Module... modules) {
String hint = checkNotNull(blobStore.getHost(), "host");
checkNotNull(account, "account");
checkNotNull(key, "key");
String propertiesBuilderKey = String.format("%s.propertiesbuilder", hint);
String propertiesBuilderClassName = checkNotNull(
properties.getProperty(propertiesBuilderKey), propertiesBuilderKey);
String contextBuilderKey = String.format("%s.contextbuilder", hint);
String contextBuilderClassName = checkNotNull(properties.getProperty(contextBuilderKey),
contextBuilderKey);
try {
Class<HttpPropertiesBuilder> propertiesBuilderClass = (Class<HttpPropertiesBuilder>) Class
.forName(propertiesBuilderClassName);
Class<BlobStoreContextBuilder<?, ?>> contextBuilderClass = (Class<BlobStoreContextBuilder<?, ?>>) Class
.forName(contextBuilderClassName);
HttpPropertiesBuilder builder = propertiesBuilderClass.getConstructor(String.class,
String.class).newInstance(account, key);
return contextBuilderClass.getConstructor(Properties.class).newInstance(builder.build())
.withModules(modules).buildContext();
} catch (Exception e) {
throw new RuntimeException("error instantiating " + contextBuilderClassName, e);
}
}
}

View File

@ -52,7 +52,12 @@ public class BlobToHttpGetOptions implements
} }
for (String range : from[0].getRanges()) { for (String range : from[0].getRanges()) {
String[] firstLast = range.split("\\-"); String[] firstLast = range.split("\\-");
if (firstLast.length == 2)
httpOptions.range(Long.parseLong(firstLast[0]), Long.parseLong(firstLast[1])); httpOptions.range(Long.parseLong(firstLast[0]), Long.parseLong(firstLast[1]));
else if (range.startsWith("-"))
httpOptions.tail(Long.parseLong(firstLast[0]));
else
httpOptions.startAt(Long.parseLong(firstLast[0]));
} }
} }
return httpOptions; return httpOptions;

View File

@ -46,8 +46,8 @@ import com.google.common.base.Function;
/** /**
* @author Adrian Cole * @author Adrian Cole
*/ */
public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpResponse, MutableBlobMetadata>, public class ParseSystemAndUserMetadataFromHeaders implements
InvocationContext { Function<HttpResponse, MutableBlobMetadata>, InvocationContext {
private final String metadataPrefix; private final String metadataPrefix;
private final DateService dateParser; private final DateService dateParser;
private final Provider<MutableBlobMetadata> metadataFactory; private final Provider<MutableBlobMetadata> metadataFactory;
@ -69,7 +69,7 @@ public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpRespo
addETagTo(from, to); addETagTo(from, to);
addContentMD5To(from, to); addContentMD5To(from, to);
parseLastModifiedOrThrowException(from, to); parseLastModifiedOrThrowException(from, to);
setContentLengthOrThrowException(from, to); setContentLength(from, to);
addUserMetadataTo(from, to); addUserMetadataTo(from, to);
return to; return to;
} }
@ -85,13 +85,9 @@ public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpRespo
} }
@VisibleForTesting @VisibleForTesting
void setContentLengthOrThrowException(HttpResponse from, MutableBlobMetadata metadata) void setContentLength(HttpResponse from, MutableBlobMetadata metadata) throws HttpException {
throws HttpException {
String contentLength = from.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH); String contentLength = from.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH);
if (contentLength == null) metadata.setSize(contentLength == null ? 0 : Long.parseLong(contentLength));
throw new HttpException(HttpHeaders.CONTENT_LENGTH + " not found in headers");
else
metadata.setSize(Long.parseLong(contentLength));
} }
@VisibleForTesting @VisibleForTesting
@ -100,7 +96,7 @@ public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpRespo
String lastModified = from.getFirstHeaderOrNull(HttpHeaders.LAST_MODIFIED); String lastModified = from.getFirstHeaderOrNull(HttpHeaders.LAST_MODIFIED);
if (lastModified == null) if (lastModified == null)
throw new HttpException(HttpHeaders.LAST_MODIFIED + " header not present in response: " throw new HttpException(HttpHeaders.LAST_MODIFIED + " header not present in response: "
+ from); + from.getStatusLine());
metadata.setLastModified(dateParser.rfc822DateParse(lastModified)); metadata.setLastModified(dateParser.rfc822DateParse(lastModified));
if (metadata.getLastModified() == null) if (metadata.getLastModified() == null)
throw new HttpException("could not parse: " + HttpHeaders.LAST_MODIFIED + ": " throw new HttpException("could not parse: " + HttpHeaders.LAST_MODIFIED + ": "

View File

@ -0,0 +1,50 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore.functions;
import javax.inject.Singleton;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.internal.ResourceMetadataImpl;
import org.jclouds.blobstore.reference.BlobStoreConstants;
import com.google.common.base.Function;
@Singleton
public class ResourceMetadataToRelativePathResourceMetadata implements
Function<ResourceMetadata, ResourceMetadata> {
public ResourceMetadata apply(ResourceMetadata md) {
String name = md.getName();
for (String suffix : BlobStoreConstants.DIRECTORY_SUFFIXES) {
if (name.endsWith(suffix))
name = name.substring(0, name.length() - suffix.length());
}
return new ResourceMetadataImpl(ResourceType.RELATIVE_PATH, md.getId(), name, md
.getLocation(), md.getETag(), md.getSize(), md.getLastModified(), md
.getUserMetadata());
}
}

View File

@ -135,12 +135,12 @@ public abstract class BaseBlobMap<V> {
this.connection = checkNotNull(connection, "connection"); this.connection = checkNotNull(connection, "connection");
this.containerName = checkNotNull(containerName, "container"); this.containerName = checkNotNull(containerName, "container");
this.options = options; this.options = options;
if (options.getPath() == null) { if (options.getDir() == null) {
prefixer = new PassThrough<String>(); prefixer = new PassThrough<String>();
pathStripper = prefixer; pathStripper = prefixer;
} else { } else {
prefixer = new PrefixKey(options.getPath(), "/"); prefixer = new PrefixKey(options.getDir(), "/");
pathStripper = new StripPath(options.getPath(), "/"); pathStripper = new StripPath(options.getDir(), "/");
} }
this.getAllBlobs = checkNotNull(getAllBlobs, "getAllBlobs"); this.getAllBlobs = checkNotNull(getAllBlobs, "getAllBlobs");
@ -225,7 +225,7 @@ public abstract class BaseBlobMap<V> {
public SortedSet<? extends BlobMetadata> list() { public SortedSet<? extends BlobMetadata> list() {
SortedSet<? extends BlobMetadata> returnVal = getAllBlobMetadata.execute(containerName, SortedSet<? extends BlobMetadata> returnVal = getAllBlobMetadata.execute(containerName,
options); options);
if (options.getPath() != null) { if (options.getDir() != null) {
returnVal = Sets.newTreeSet(Iterables.transform(returnVal, returnVal = Sets.newTreeSet(Iterables.transform(returnVal,
new Function<BlobMetadata, BlobMetadata>() { new Function<BlobMetadata, BlobMetadata>() {

View File

@ -77,7 +77,7 @@ public class BlobStoreContextImpl<A, S> extends RestContextImpl<A, S> implements
String prefix = BlobStoreUtils.parsePrefixFromPath(path); String prefix = BlobStoreUtils.parsePrefixFromPath(path);
ListContainerOptions options = new ListContainerOptions(); ListContainerOptions options = new ListContainerOptions();
if (prefix != null) if (prefix != null)
options.underPath(prefix); options.inDirectory(prefix);
return blobMapFactory.create(container, options); return blobMapFactory.create(container, options);
} }
@ -87,7 +87,7 @@ public class BlobStoreContextImpl<A, S> extends RestContextImpl<A, S> implements
String prefix = BlobStoreUtils.parsePrefixFromPath(path); String prefix = BlobStoreUtils.parsePrefixFromPath(path);
ListContainerOptions options = new ListContainerOptions(); ListContainerOptions options = new ListContainerOptions();
if (prefix != null) if (prefix != null)
options.underPath(prefix); options.inDirectory(prefix);
return inputStreamMapFactory.create(container, options); return inputStreamMapFactory.create(container, options);
} }

View File

@ -0,0 +1,143 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore.internal;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jclouds.util.Utils;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
/**
* Used to extract the URI and authentication data from a String. Note that the java URI class
* breaks, if there are special characters like '/' present. Otherwise, we wouldn't need this class,
* and we could simply use URI.create("uri").getUserData();
*
* @author Adrian Cole
*/
public class LocationAndCredentials {
public static final Pattern URI_PATTERN = Pattern.compile("([a-z0-9]+)://([^:]*):(.*)@(.*)");
public static final Pattern PATTERN_THAT_BREAKS_URI = Pattern.compile("[a-z0-9]+://.*/.*@.*"); // slash
// in
// userdata
// breaks
// URI.create()
public final URI uri;
public final String acccount;
public final String key;
public LocationAndCredentials(URI uri, String acccount, String key) {
this.uri = checkNotNull(uri, "uri");
checkArgument(uri.getHost() != null, "type missing from %s", uri.toASCIIString());
checkArgument(uri.getPath() != null, "path missing from %s", uri.toASCIIString());
this.acccount = acccount;
this.key = key;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((acccount == null) ? 0 : acccount.hashCode());
result = prime * result + ((key == null) ? 0 : key.hashCode());
result = prime * result + ((uri == null) ? 0 : uri.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LocationAndCredentials other = (LocationAndCredentials) obj;
if (acccount == null) {
if (other.acccount != null)
return false;
} else if (!acccount.equals(other.acccount))
return false;
if (key == null) {
if (other.key != null)
return false;
} else if (!key.equals(other.key))
return false;
if (uri == null) {
if (other.uri != null)
return false;
} else if (!uri.equals(other.uri))
return false;
return true;
}
public static LocationAndCredentials parse(String uriPath) {
if (uriPath.indexOf('@') != 1) {
List<String> parts = Lists.newArrayList(Splitter.on('@').split(uriPath));
String path = parts.remove(parts.size() - 1);
parts.add(Utils.urlEncode(path, '/', ':'));
uriPath = Joiner.on('@').join(parts);
} else {
List<String> parts = Lists.newArrayList(Splitter.on('/').split(uriPath));
String path = parts.remove(parts.size() - 1);
parts.add(Utils.urlEncode(path, ':'));
uriPath = Joiner.on('/').join(parts);
}
LocationAndCredentials locationAndCredentials;
if (PATTERN_THAT_BREAKS_URI.matcher(uriPath).matches()) {
// Compile and use regular expression
Matcher matcher = URI_PATTERN.matcher(uriPath);
if (matcher.find()) {
String scheme = matcher.group(1);
String rest = matcher.group(4);
String account = matcher.group(2);
String key = matcher.group(3);
locationAndCredentials = new LocationAndCredentials(URI.create(String.format("%s://%s",
scheme, rest)), account, key);
} else {
throw new IllegalArgumentException("bad syntax");
}
} else {
URI uri = URI.create(uriPath);
String account = null;
String key = null;
if (uri.getUserInfo() != null) {
List<String> userInfo = Lists.newArrayList(Splitter.on(':').split(uri.getUserInfo()));
account = userInfo.get(0);
key = userInfo.size() > 1 ? userInfo.get(1) : null;
}
locationAndCredentials = new LocationAndCredentials(uri, account, key);
}
return locationAndCredentials;
}
}

View File

@ -65,6 +65,15 @@ public class GetOptions {
return this; return this;
} }
/**
* download the specified range of the object.
*/
public GetOptions startAt(long start) {
checkArgument(start >= 0, "start must be >= 0");
getRanges().add(String.format("%d-", start));
return this;
}
/** /**
* Only return the object if it has changed since this time. * Only return the object if it has changed since this time.
* <p /> * <p />

View File

@ -29,26 +29,26 @@ import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* Contains options supported in the list container operation. <h2> * Contains options supported in the list container operation. <h2>
* Usage</h2> The recommended way to instantiate a ListOptions object is to statically import * Usage</h2> The recommended way to instantiate a ListOptions object is to statically import
* ListContainerOptions.* and invoke a static creation method followed by an instance mutator (if needed): * ListContainerOptions.* and invoke a static creation method followed by an instance mutator (if
* needed):
* <p/> * <p/>
* <code> * <code>
* import static org.jclouds.blobstore.options.ListContainerOptions.Builder.* * import static org.jclouds.blobstore.options.ListContainerOptions.Builder.*
* <p/> * <p/>
* BlobStore connection = // get connection * BlobStore connection = // get connection
* Future<ListResponse<ResourceMetadata>> list = connection.list("container",underPath("home/users").maxResults(1000)); * Future<ListResponse<ResourceMetadata>> list = connection.list("container",inDirectory("home/users").maxResults(1000));
* <code> * <code>
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class ListContainerOptions extends ListOptions { public class ListContainerOptions extends ListOptions {
private String path; private String dir;
private boolean recursive; private boolean recursive;
public String getDir() {
public String getPath() { return dir;
return path;
} }
public boolean isRecursive() { public boolean isRecursive() {
@ -59,9 +59,10 @@ public class ListContainerOptions extends ListOptions {
* Returns a pseudo-directory listing. * Returns a pseudo-directory listing.
* *
*/ */
public ListContainerOptions underPath(String path) { public ListContainerOptions inDirectory(String dir) {
checkArgument(!recursive, "path and recursive combination currently not supported"); checkArgument(!recursive, "dir and recursive combination currently not supported");
this.path = checkNotNull(path, "path"); this.dir = checkNotNull(dir, "dir");
checkArgument(!dir.equals("/"), "dir must not be a slash");
return this; return this;
} }
@ -83,7 +84,7 @@ public class ListContainerOptions extends ListOptions {
* return a listing of all objects inside the store, recursively. * return a listing of all objects inside the store, recursively.
*/ */
public ListContainerOptions recursive() { public ListContainerOptions recursive() {
// checkArgument(path == null, "path and recursive combination currently not supported"); // checkArgument(path == null, "path and recursive combination currently not supported");
this.recursive = true; this.recursive = true;
return this; return this;
} }
@ -91,11 +92,11 @@ public class ListContainerOptions extends ListOptions {
public static class Builder { public static class Builder {
/** /**
* @see ListContainerOptions#underPath(String) * @see ListContainerOptions#inDirectory(String)
*/ */
public static ListContainerOptions underPath(String path) { public static ListContainerOptions inDirectory(String directory) {
ListContainerOptions options = new ListContainerOptions(); ListContainerOptions options = new ListContainerOptions();
return options.underPath(path); return options.inDirectory(directory);
} }
/** /**

View File

@ -29,6 +29,29 @@ package org.jclouds.blobstore.reference;
* @author Adrian Cole * @author Adrian Cole
*/ */
public interface BlobStoreConstants { public interface BlobStoreConstants {
/**
* <p/>
* To interoperate with other S3 tools, we also accept the following:
* <ul>
* <li>an object named '#{dirpath}_$folder$' or '#{dirpath}/' denoting a directory marker</li>
* <li>an object with content type set to 'application/directory' denoting a directory marker</li>
* <li>if there exists any objects with the prefix "#{dirpath}/", then the directory is said to
* exist</li>
* <li>if both a file with the name of a directory and a marker for that directory exists, then
* the *file masks the directory*, and the directory is never returned.</li>
* </ul>
*/
public static final String DIRECTORY_SUFFIX_ROOT = "/";
public static final String DIRECTORY_SUFFIX_FOLDER = "_$folder$";
public static final String[] DIRECTORY_SUFFIXES = { DIRECTORY_SUFFIX_FOLDER,
DIRECTORY_SUFFIX_ROOT };
/**
* Key-value implementations of BlobStore, such as S3, do not have directories. We use an empty
* object '#{dirpath}_$folder$' with content type set to 'application/directory'.
*/
public static final String PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX = "jclouds.blobstore.directorysuffix";
/** /**
* comma-separated, fully qualified class names of implementations of BlobStoreContextBuilder * comma-separated, fully qualified class names of implementations of BlobStoreContextBuilder
* *

View File

@ -0,0 +1,41 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore.strategy;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.strategy.internal.MarkersGetDirectoryStrategy;
import com.google.inject.ImplementedBy;
/**
* Gets a directory or throws KeyNotFoundException
*
* @author Adrian Cole
*/
@ImplementedBy(MarkersGetDirectoryStrategy.class)
public interface GetDirectoryStrategy {
ResourceMetadata execute(AsyncBlobStore connection, String containerName, String directory);
}

View File

@ -0,0 +1,40 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore.strategy;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.strategy.internal.MarkersIsDirectoryStrategy;
import com.google.inject.ImplementedBy;
/**
* Determines if a directory exists or not.
*
* @author Adrian Cole
*/
@ImplementedBy(MarkersIsDirectoryStrategy.class)
public interface IsDirectoryStrategy {
boolean execute(ResourceMetadata metadata);
}

View File

@ -0,0 +1,40 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore.strategy;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.strategy.internal.MarkerFileMkdirStrategy;
import com.google.inject.ImplementedBy;
/**
* Creates a directory
*
* @author Adrian Cole
*/
@ImplementedBy(MarkerFileMkdirStrategy.class)
public interface MkdirStrategy {
void execute(AsyncBlobStore connection, String containerName, String directory);
}

View File

@ -0,0 +1,80 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore.strategy.internal;
import java.util.concurrent.TimeUnit;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.internal.BlobRuntimeException;
import org.jclouds.blobstore.reference.BlobStoreConstants;
import org.jclouds.blobstore.strategy.MkdirStrategy;
import org.jclouds.util.Utils;
import com.google.inject.Inject;
/**
* Key-value implementations of BlobStore, such as S3, do not have directories. In following the
* rackspace cloud files project, we use an empty object '#{dirpath}' with content type set to
* 'application/directory'.
*
* @author Adrian Cole
*/
@Singleton
public class MarkerFileMkdirStrategy implements MkdirStrategy {
/**
* maximum duration of an blob Request
*/
@Inject(optional = true)
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT)
protected long requestTimeoutMilliseconds = 30000;
@Inject(optional = true)
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX)
protected String directorySuffix = "";
public void execute(AsyncBlobStore connection, String containerName, String directory) {
try {
if (!connection.directoryExists(containerName, directory).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS)) {
Blob blob = connection.newBlob();
blob.getMetadata().setName(directory + directorySuffix);
blob.setData("");
blob.getMetadata().setContentType("application/directory");
connection.putBlob(containerName, blob).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);
}
} catch (Exception e) {
e = Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
if (!(e instanceof KeyNotFoundException))
throw new BlobRuntimeException("Error creating marker directory: " + containerName
+ "/" + directory, e);
}
}
}

View File

@ -0,0 +1,93 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore.strategy.internal;
import java.util.concurrent.TimeUnit;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.functions.ResourceMetadataToRelativePathResourceMetadata;
import org.jclouds.blobstore.internal.BlobRuntimeException;
import org.jclouds.blobstore.reference.BlobStoreConstants;
import org.jclouds.blobstore.strategy.GetDirectoryStrategy;
import org.jclouds.util.Utils;
import com.google.inject.Inject;
/**
* Key-value implementations of BlobStore, such as S3, do not have directories. In following the
* rackspace cloud files project, we use an empty object '#{dirpath}' with content type set to
* 'application/directory'.
*
* <p/>
* To interoperate with other S3 tools, we accept the following ways to tell if the directory
* exists:
* <ul>
* <li>an object named '#{dirpath}_$folder$' or '#{dirpath}/' denoting a directory marker</li>
* <li>an object with content type set to 'application/directory' denoting a directory marker</li>
* <li>if there exists any objects with the prefix "#{dirpath}/", then the directory is said to
* exist</li>
* <li>if both a file with the name of a directory and a marker for that directory exists, then the
* *file masks the directory*, and the directory is never returned.</li>
* </ul>
*
* @see MarkerFileMkdirStrategy
* @author Adrian Cole
*/
@Singleton
public class MarkersGetDirectoryStrategy implements GetDirectoryStrategy {
/**
* maximum duration of an blob Request
*/
@Inject(optional = true)
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT)
protected long requestTimeoutMilliseconds = 30000;
protected final ResourceMetadataToRelativePathResourceMetadata resource2Directory;
@Inject
public MarkersGetDirectoryStrategy(ResourceMetadataToRelativePathResourceMetadata resource2Directory) {
this.resource2Directory = resource2Directory;
}
public ResourceMetadata execute(AsyncBlobStore connection, String containerName, String directory) {
for (String suffix : BlobStoreConstants.DIRECTORY_SUFFIXES) {
try {
return resource2Directory.apply(connection.blobMetadata(containerName,
directory + suffix).get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS));
} catch (KeyNotFoundException e) {
} catch (Exception e) {
e = Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
if (!(e instanceof KeyNotFoundException))
throw new BlobRuntimeException("Error determining if a directory exists at: "
+ containerName + "/" + directory, e);
}
}
throw new KeyNotFoundException(containerName, directory);
}
}

View File

@ -0,0 +1,59 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore.strategy.internal;
import javax.inject.Singleton;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.reference.BlobStoreConstants;
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
/**
*
* @author Adrian Cole
*/
@Singleton
public class MarkersIsDirectoryStrategy implements IsDirectoryStrategy {
public boolean execute(ResourceMetadata metadata) {
switch (metadata.getType()) {
case CONTAINER:
case FOLDER:
case RELATIVE_PATH:
return true;
case BLOB:
BlobMetadata blobMd = (BlobMetadata) metadata;
if (blobMd.getContentType() != null
&& blobMd.getContentType().equals("application/directory"))
return true;
for (String suffix : BlobStoreConstants.DIRECTORY_SUFFIXES) {
if (metadata.getName().endsWith(suffix)) {
return true;
}
}
}
return false;
}
}

View File

@ -28,7 +28,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.util.Utils; import org.jclouds.util.Utils;
/** /**
@ -37,6 +40,26 @@ import org.jclouds.util.Utils;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class BlobStoreUtils { public class BlobStoreUtils {
public static Blob newBlob(BlobStore blobStore, ResourceMetadata blobMeta) {
Blob blob = blobStore.newBlob();
if (blobMeta instanceof BlobMetadata) {
blob.getMetadata().setContentMD5(((BlobMetadata) blobMeta).getContentMD5());
blob.getMetadata().setContentType(((BlobMetadata) blobMeta).getContentType());
}
blob.getMetadata().setETag(blobMeta.getETag());
blob.getMetadata().setId(blobMeta.getId());
blob.getMetadata().setLastModified(blobMeta.getLastModified());
blob.getMetadata().setLocation(blobMeta.getLocation());
blob.getMetadata().setName(blobMeta.getName());
blob.getMetadata().setUserMetadata(blobMeta.getUserMetadata());
return blob;
}
public static Blob newBlob(BlobStore blobStore, String name) {
Blob blob = blobStore.newBlob();
blob.getMetadata().setName(name);
return blob;
}
public static String parseContainerFromPath(String path) { public static String parseContainerFromPath(String path) {
String container = path; String container = path;

View File

@ -84,7 +84,7 @@ public class GetOptions extends BaseHttpRequestOptions {
*/ */
public GetOptions startAt(long start) { public GetOptions startAt(long start) {
checkArgument(start >= 0, "start must be >= 0"); checkArgument(start >= 0, "start must be >= 0");
ranges.add(String.format("%d-", start)); ranges.add(String.format("%d-%d", start, Long.MAX_VALUE));
return this; return this;
} }

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright (A) 2009 Cloud Conscious, LLC. <info@cloudconscious.com> * Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
* *
* ==================================================================== * ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.rest.domain; package org.jclouds.rest.domain;
import org.jclouds.rest.internal.NamedResourceImpl; import org.jclouds.rest.internal.NamedResourceImpl;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.rest.internal; package org.jclouds.rest.internal;
import java.net.URI; import java.net.URI;

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright (A) 2009 Cloud Conscious, LLC. <info@cloudconscious.com> * Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
* *
* ==================================================================== * ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one

View File

@ -77,6 +77,8 @@ public class Utils {
* Web browsers do not always handle '+' characters well, use the well-supported '%20' instead. * Web browsers do not always handle '+' characters well, use the well-supported '%20' instead.
*/ */
public static String urlEncode(String in, char... skipEncode) { public static String urlEncode(String in, char... skipEncode) {
if (isUrlEncoded(in))
return in;
try { try {
String returnVal = URLEncoder.encode(in, "UTF-8").replaceAll("\\+", "%20").replaceAll( String returnVal = URLEncoder.encode(in, "UTF-8").replaceAll("\\+", "%20").replaceAll(
"\\*", "%2A").replaceAll("%7E", "~"); "\\*", "%2A").replaceAll("%7E", "~");
@ -89,6 +91,10 @@ public class Utils {
} }
} }
public static boolean isUrlEncoded(String in) {
return in.matches(".*%[a-fA-F0-9][a-fA-F0-9].*");
}
static Map<String, String> plainToEncodedChars = new MapMaker() static Map<String, String> plainToEncodedChars = new MapMaker()
.makeComputingMap(new Function<String, String>() { .makeComputingMap(new Function<String, String>() {
public String apply(String plain) { public String apply(String plain) {

View File

@ -0,0 +1,66 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.URI;
import java.util.Iterator;
import org.testng.annotations.Test;
import com.google.common.base.Splitter;
/**
* Tests parsing of a request
*
* @author Adrian Cole
*/
@Test(testName = "blobstore.BlobStoreContextFactoryTest")
public class BlobStoreContextFactoryTest {
public void test() throws IOException {
URI blobStore = URI.create("service://account:key@container/path");
assertEquals(blobStore.getScheme(), "service");
Iterator<String> accountKey = Splitter.on(":").split(
checkNotNull(blobStore.getUserInfo(), "userInfo")).iterator();
assertEquals(accountKey.next(), "account");
assertEquals(accountKey.next(), "key");
assertEquals(blobStore.getHost(), "container");
assertEquals(blobStore.getPath(), "/path");
}
public void testNoPassword() throws IOException {
URI blobStore = URI.create("service://account@container/path");
assertEquals(blobStore.getScheme(), "service");
Iterator<String> accountKey = Splitter.on(":").split(
checkNotNull(blobStore.getUserInfo(), "userInfo")).iterator();
assertEquals(accountKey.next(), "account");
assertEquals(blobStore.getHost(), "container");
assertEquals(blobStore.getPath(), "/path");
}
}

View File

@ -0,0 +1,80 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore.functions;
import static org.testng.Assert.assertEquals;
import javax.inject.Provider;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.ResourceType;
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.testng.annotations.Test;
public class BlobMetadataToRelativePathResourceMetadataTest {
private ResourceMetadataToRelativePathResourceMetadata parser = new ResourceMetadataToRelativePathResourceMetadata();
private Provider<MutableBlobMetadata> blobMetadataProvider = new Provider<MutableBlobMetadata>() {
public MutableBlobMetadata get() {
return new MutableBlobMetadataImpl();
}
};
@Test
public void test1() {
MutableBlobMetadata md = blobMetadataProvider.get();
md.setName("dir/");
md.setId("dir/");
ResourceMetadata rd = parser.apply(md);
assertEquals(rd.getName(), "dir");
assertEquals(rd.getId(), "dir/");
assertEquals(rd.getType(), ResourceType.RELATIVE_PATH);
}
@Test
public void test2() {
MutableBlobMetadata md = blobMetadataProvider.get();
md.setName("dir_$folder$");
md.setId("dir_$folder$");
ResourceMetadata rd = parser.apply(md);
assertEquals(rd.getName(), "dir");
assertEquals(rd.getId(), "dir_$folder$");
assertEquals(rd.getType(), ResourceType.RELATIVE_PATH);
}
@Test
public void testNoNameChange() {
MutableBlobMetadata md = blobMetadataProvider.get();
md.setName("dir");
md.setId("dir");
ResourceMetadata rd = parser.apply(md);
assertEquals(rd.getName(), "dir");
assertEquals(rd.getId(), "dir");
assertEquals(rd.getType(), ResourceType.RELATIVE_PATH);
}
}

View File

@ -85,15 +85,15 @@ public class ParseBlobMetadataFromHeadersTest {
HttpResponse from = new HttpResponse(); HttpResponse from = new HttpResponse();
from.getHeaders().put(HttpHeaders.CONTENT_LENGTH, "100"); from.getHeaders().put(HttpHeaders.CONTENT_LENGTH, "100");
MutableBlobMetadata metadata = blobMetadataProvider.get(); MutableBlobMetadata metadata = blobMetadataProvider.get();
parser.setContentLengthOrThrowException(from, metadata); parser.setContentLength(from, metadata);
assertEquals(metadata.getSize(), new Long(100)); assertEquals(metadata.getSize(), new Long(100));
} }
@Test(expectedExceptions = HttpException.class) public void testSetContentLengthNoHeader() {
public void testSetContentLengthException() {
HttpResponse from = new HttpResponse(); HttpResponse from = new HttpResponse();
MutableBlobMetadata metadata = blobMetadataProvider.get(); MutableBlobMetadata metadata = blobMetadataProvider.get();
parser.setContentLengthOrThrowException(from, metadata); parser.setContentLength(from, metadata);
assertEquals(metadata.getSize(), new Long(0));
} }
@Test @Test

View File

@ -25,6 +25,7 @@ package org.jclouds.blobstore.integration;
import java.net.URI; import java.net.URI;
import java.util.List; import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -54,6 +55,14 @@ import com.google.inject.TypeLiteral;
*/ */
public class StubBlobStoreContextBuilder extends BlobStoreContextBuilder<AsyncBlobStore, BlobStore> { public class StubBlobStoreContextBuilder extends BlobStoreContextBuilder<AsyncBlobStore, BlobStore> {
/**
* This is only to have the same syntax.
*
*/
public StubBlobStoreContextBuilder(Properties props) {
this();
}
public StubBlobStoreContextBuilder() { public StubBlobStoreContextBuilder() {
super(new TypeLiteral<AsyncBlobStore>() { super(new TypeLiteral<AsyncBlobStore>() {
}, new TypeLiteral<BlobStore>() { }, new TypeLiteral<BlobStore>() {

View File

@ -0,0 +1,45 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore.integration;
import java.util.Properties;
import org.jclouds.http.HttpPropertiesBuilder;
/**
* Builds properties used in Stub Connections
*
* @author Adrian Cole
*/
public class StubPropertiesBuilder extends HttpPropertiesBuilder {
public StubPropertiesBuilder(Properties properties) {
super(properties);
}
public StubPropertiesBuilder(String id, String secret) {
super();
}
}

View File

@ -397,13 +397,13 @@ public class BaseBlobStoreIntegrationTest<A, S> {
protected static void deleteContainer(final BlobStoreContext<?, ?> context, final String name) protected static void deleteContainer(final BlobStoreContext<?, ?> context, final String name)
throws InterruptedException { throws InterruptedException {
if (context.getBlobStore().exists(name)) { if (context.getBlobStore().containerExists(name)) {
System.err.printf("*** deleting container %s...%n", name); System.err.printf("*** deleting container %s...%n", name);
context.getBlobStore().deleteContainer(name); context.getBlobStore().deleteContainer(name);
assertConsistencyAware(context, new Runnable() { assertConsistencyAware(context, new Runnable() {
public void run() { public void run() {
try { try {
assert !context.getBlobStore().exists(name) : "container " + name assert !context.getBlobStore().containerExists(name) : "container " + name
+ " still exists"; + " still exists";
} catch (Exception e) { } catch (Exception e) {
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e); Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);

View File

@ -25,7 +25,7 @@ package org.jclouds.blobstore.integration.internal;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.afterMarker; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.afterMarker;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.maxResults; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.maxResults;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.underPath; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.inDirectory;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@ -47,7 +47,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
@Test(groups = { "integration", "live" }) @Test(groups = { "integration", "live" })
public void containerDoesntExist() { public void containerDoesntExist() {
assert !context.getBlobStore().exists("forgetaboutit"); assert !context.getBlobStore().containerExists("forgetaboutit");
} }
@Test(groups = { "integration", "live" }) @Test(groups = { "integration", "live" })
@ -112,7 +112,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
add15UnderRoot(containerName); add15UnderRoot(containerName);
ListContainerResponse<? extends ResourceMetadata> container = context.getBlobStore().list( ListContainerResponse<? extends ResourceMetadata> container = context.getBlobStore().list(
containerName, underPath("apps/")); containerName, inDirectory("apps/"));
assert !container.isTruncated(); assert !container.isTruncated();
assertEquals(container.size(), 10); assertEquals(container.size(), 10);
assertEquals(container.getPath(), "apps/"); assertEquals(container.getPath(), "apps/");
@ -141,7 +141,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
public void containerExists() throws InterruptedException { public void containerExists() throws InterruptedException {
String containerName = getContainerName(); String containerName = getContainerName();
try { try {
assert context.getBlobStore().exists(containerName); assert context.getBlobStore().containerExists(containerName);
} finally { } finally {
returnContainer(containerName); returnContainer(containerName);
} }
@ -175,7 +175,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
assertConsistencyAware(new Runnable() { assertConsistencyAware(new Runnable() {
public void run() { public void run() {
try { try {
assert !context.getBlobStore().exists(containerName) : "container " + containerName assert !context.getBlobStore().containerExists(containerName) : "container " + containerName
+ " still exists"; + " still exists";
} catch (Exception e) { } catch (Exception e) {
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e); Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);

View File

@ -41,9 +41,11 @@ import java.util.Map;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@ -72,6 +74,9 @@ import org.jclouds.blobstore.domain.internal.MutableResourceMetadataImpl;
import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions; import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions;
import org.jclouds.blobstore.options.GetOptions; import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.strategy.GetDirectoryStrategy;
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
import org.jclouds.blobstore.strategy.MkdirStrategy;
import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
@ -103,17 +108,29 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
private final ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs; private final ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs;
protected final Blob.Factory blobProvider; protected final Blob.Factory blobProvider;
protected final HttpGetOptionsListToGetOptions httpGetOptionsConverter; protected final HttpGetOptionsListToGetOptions httpGetOptionsConverter;
protected final GetDirectoryStrategy getDirectoryStrategy;
protected final MkdirStrategy mkdirStrategy;
private final IsDirectoryStrategy isDirectoryStrategy;
protected final ExecutorService service;
@Inject @Inject
protected StubAsyncBlobStore( protected StubAsyncBlobStore(
ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs, ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs,
DateService dateService, Blob.Factory blobProvider, DateService dateService, Blob.Factory blobProvider,
HttpGetOptionsListToGetOptions httpGetOptionsConverter) { GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy,
IsDirectoryStrategy isDirectoryStrategy,
HttpGetOptionsListToGetOptions httpGetOptionsConverter, ExecutorService service) {
this.dateService = checkNotNull(dateService, "dateService"); this.dateService = checkNotNull(dateService, "dateService");
this.containerToBlobs = checkNotNull(containerToBlobs, "containerToBlobs"); this.containerToBlobs = checkNotNull(containerToBlobs, "containerToBlobs");
this.blobProvider = checkNotNull(blobProvider, "blobProvider"); this.blobProvider = checkNotNull(blobProvider, "blobProvider");
this.getDirectoryStrategy = checkNotNull(getDirectoryStrategy, "getDirectoryStrategy");
this.mkdirStrategy = checkNotNull(mkdirStrategy, "mkdirStrategy");
this.isDirectoryStrategy = checkNotNull(isDirectoryStrategy, "isDirectoryStrategy");
this.httpGetOptionsConverter = checkNotNull(httpGetOptionsConverter, this.httpGetOptionsConverter = checkNotNull(httpGetOptionsConverter,
"httpGetOptionsConverter"); "httpGetOptionsConverter");
this.service = checkNotNull(service, "service");
getContainerToBlobs().put("stub", new ConcurrentHashMap<String, Blob>());
} }
/** /**
@ -170,7 +187,10 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
SortedSet<ResourceMetadata> contents = Sets.newTreeSet(Iterables.transform(realContents SortedSet<ResourceMetadata> contents = Sets.newTreeSet(Iterables.transform(realContents
.keySet(), new Function<String, ResourceMetadata>() { .keySet(), new Function<String, ResourceMetadata>() {
public ResourceMetadata apply(String key) { public ResourceMetadata apply(String key) {
return copy(realContents.get(key).getMetadata()); MutableBlobMetadata md = copy(realContents.get(key).getMetadata());
if (isDirectoryStrategy.execute(md))
md.setType(ResourceType.RELATIVE_PATH);
return md;
} }
})); }));
@ -186,7 +206,7 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
contents.remove(lastMarkerMetadata); contents.remove(lastMarkerMetadata);
} }
final String prefix = options.getPath(); final String prefix = options.getDir();
if (prefix != null) { if (prefix != null) {
contents = Sets.newTreeSet(Iterables.filter(contents, contents = Sets.newTreeSet(Iterables.filter(contents,
new Predicate<ResourceMetadata>() { new Predicate<ResourceMetadata>() {
@ -315,7 +335,7 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
}; };
} }
public Future<Boolean> exists(final String container) { public Future<Boolean> containerExists(final String container) {
return new FutureBase<Boolean>() { return new FutureBase<Boolean>() {
public Boolean get() throws InterruptedException, ExecutionException { public Boolean get() throws InterruptedException, ExecutionException {
return getContainerToBlobs().containsKey(container); return getContainerToBlobs().containsKey(container);
@ -490,9 +510,10 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
new RuntimeException("bucketName not found: " + bucketName); new RuntimeException("bucketName not found: " + bucketName);
} }
try { try {
byte[] data = toByteArray(object.getData());
object.getMetadata().setSize(data.length);
MutableBlobMetadata newMd = copy(object.getMetadata()); MutableBlobMetadata newMd = copy(object.getMetadata());
newMd.setLastModified(new DateTime()); newMd.setLastModified(new DateTime());
byte[] data = toByteArray(object.getData());
final byte[] md5 = HttpUtils.md5(data); final byte[] md5 = HttpUtils.md5(data);
final String eTag = HttpUtils.toHexString(md5); final String eTag = HttpUtils.toHexString(md5);
newMd.setETag(eTag); newMd.setETag(eTag);
@ -573,10 +594,10 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
for (String s : options.getRanges()) { for (String s : options.getRanges()) {
if (s.startsWith("-")) { if (s.startsWith("-")) {
int length = Integer.parseInt(s); int length = Integer.parseInt(s.substring(1));
out.write(data, data.length - length, length); out.write(data, data.length - length, length);
} else if (s.endsWith("-")) { } else if (s.endsWith("-")) {
int offset = Integer.parseInt(s); int offset = Integer.parseInt(s.substring(0, s.length()-1));
out.write(data, offset, data.length - offset); out.write(data, offset, data.length - offset);
} else if (s.contains("-")) { } else if (s.contains("-")) {
String[] firstLast = s.split("\\-"); String[] firstLast = s.split("\\-");
@ -632,6 +653,31 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
}; };
} }
public Future<Void> createDirectory(final String container, final String directory) {
return service.submit(new Callable<Void>() {
public Void call() throws Exception {
mkdirStrategy.execute(StubAsyncBlobStore.this, container, directory);
return null;
}
});
}
public Future<Boolean> directoryExists(final String container, final String directory) {
return service.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
try {
return getDirectoryStrategy.execute(StubAsyncBlobStore.this, container, directory) != null;
} catch (KeyNotFoundException e) {
return false;
}
}
});
}
public Blob newBlob() { public Blob newBlob() {
return blobProvider.create(null); return blobProvider.create(null);
} }

View File

@ -0,0 +1,86 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.blobstore.internal;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import org.jclouds.blobstore.internal.LocationAndCredentials;
import org.testng.annotations.Test;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "blobstore.LocationAndCredentialsTest")
public class LocationAndCredentialsTest {
public void testAzure() {
LocationAndCredentials creds = LocationAndCredentials
.parse("blobstore://account:Base64==@azureblob/container-hyphen/prefix");
assertEquals(creds.acccount, "account");
assertEquals(creds.key, "Base64==");
assertEquals(creds.uri, URI
.create("blobstore://account:Base64==@azureblob/container-hyphen/prefix"));
}
public void testCloudFiles() {
LocationAndCredentials creds = LocationAndCredentials
.parse("blobstore://account:h3c@cloudfiles/container-hyphen/prefix");
assertEquals(creds.acccount, "account");
assertEquals(creds.key, "h3c");
assertEquals(creds.uri, URI
.create("blobstore://account:h3c@cloudfiles/container-hyphen/prefix"));
}
public void testS3() {
LocationAndCredentials creds = LocationAndCredentials
.parse("blobstore://0AB:aA+/0@s3/buck-et/prefix");
assertEquals(creds.acccount, "0AB");
assertEquals(creds.key, "aA+/0");
assertEquals(creds.uri, URI.create("blobstore://s3/buck-et/prefix"));
}
public void testS3Space() {
LocationAndCredentials creds = LocationAndCredentials
.parse("blobstore://0AB:aA+/0@s3/buck-et/pre fix");
assertEquals(creds.acccount, "0AB");
assertEquals(creds.key, "aA+/0");
assertEquals(creds.uri, URI.create("blobstore://s3/buck-et/pre%20fix"));
}
public void testPercent() {
LocationAndCredentials creds = LocationAndCredentials
.parse("https://jclouds.blob.core.windows.net/jclouds-getpath/write-tests/file1%.txt");
assertEquals(creds.acccount, null);
assertEquals(creds.key, null);
assertEquals(
creds.uri,
URI
.create("https://jclouds.blob.core.windows.net/jclouds-getpath/write-tests/file1%25.txt"));
}
}

View File

@ -26,7 +26,7 @@ package org.jclouds.blobstore.options;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.afterMarker; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.afterMarker;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.maxResults; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.maxResults;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.underPath; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.inDirectory;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
@ -54,21 +54,21 @@ public class ListOptionsTest {
@Test @Test
public void testPath() { public void testPath() {
ListContainerOptions options = new ListContainerOptions(); ListContainerOptions options = new ListContainerOptions();
options.underPath("test"); options.inDirectory("test");
assertEquals(options.getPath(), "test"); assertEquals(options.getDir(), "test");
} }
@Test @Test
public void testPathStatic() { public void testPathStatic() {
ListContainerOptions options = underPath("test"); ListContainerOptions options = inDirectory("test");
assertEquals(options.getPath(), "test"); assertEquals(options.getDir(), "test");
} }
@Test @Test
public void testTwoOptions() { public void testTwoOptions() {
ListContainerOptions options = new ListContainerOptions(); ListContainerOptions options = new ListContainerOptions();
options.underPath("test").maxResults(1); options.inDirectory("test").maxResults(1);
assertEquals(options.getPath(), "test"); assertEquals(options.getDir(), "test");
assertEquals(options.getMaxResults(), new Integer(1)); assertEquals(options.getMaxResults(), new Integer(1));
} }
@ -76,12 +76,12 @@ public class ListOptionsTest {
@Test @Test
public void testNullPath() { public void testNullPath() {
ListContainerOptions options = new ListContainerOptions(); ListContainerOptions options = new ListContainerOptions();
assertEquals(options.getPath(), null); assertEquals(options.getDir(), null);
} }
@Test(expectedExceptions = NullPointerException.class) @Test(expectedExceptions = NullPointerException.class)
public void testPathNPE() { public void testPathNPE() {
underPath(null); inDirectory(null);
} }
@Test @Test

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.compute; package org.jclouds.compute;
import java.util.SortedSet; import java.util.SortedSet;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.compute; package org.jclouds.compute;
import com.google.common.base.Service; import com.google.common.base.Service;

View File

@ -1,3 +1,26 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.compute; package org.jclouds.compute;
import java.util.SortedSet; import java.util.SortedSet;

View File

@ -1,7 +1,28 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.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.compute; package org.jclouds.compute;
import com.google.common.base.Service;
import java.util.SortedSet; import java.util.SortedSet;
/** /**

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