mirror of https://github.com/apache/jclouds.git
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:
parent
8bbbd8c8ac
commit
9e340f286e
23
README.txt
23
README.txt
|
@ -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).
|
||||
Please publish to maven repos manually as needed.
|
||||
|
|
|
@ -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) {
|
||||
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);
|
||||
}
|
||||
|
||||
public Future<Boolean> directoryExists(String container, String directory) {
|
||||
return async.pathExists(container + "/" + directory);
|
||||
}
|
||||
|
||||
public Future<Blob> getBlob(String container, String key,
|
||||
org.jclouds.blobstore.options.GetOptions... optionsList) {
|
||||
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
|
||||
|
@ -151,8 +166,8 @@ public class AtmosAsyncBlobStore extends BaseAtmosBlobStore implements AsyncBlob
|
|||
if (optionsList[0].isRecursive()) {
|
||||
throw new UnsupportedOperationException("recursive not currently supported in emcsaas");
|
||||
}
|
||||
if (optionsList[0].getPath() != null) {
|
||||
container = container + "/" + optionsList[0].getPath();
|
||||
if (optionsList[0].getDir() != null) {
|
||||
container = container + "/" + optionsList[0].getDir();
|
||||
}
|
||||
}
|
||||
ListOptions nativeOptions = container2ContainerListOptions.apply(optionsList);
|
||||
|
|
|
@ -77,7 +77,6 @@ public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
|
|||
}
|
||||
|
||||
public void clearContainer(final String container) {
|
||||
|
||||
clearContainerStrategy.execute(container, recursive());
|
||||
}
|
||||
|
||||
|
@ -86,6 +85,10 @@ public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
|
|||
return true;// no etag
|
||||
}
|
||||
|
||||
public void createDirectory(String container, String directory) {
|
||||
sync.createDirectory(container + "/" + directory);
|
||||
}
|
||||
|
||||
public void deleteContainer(final String container) {
|
||||
clearContainerStrategy.execute(container, recursive());
|
||||
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);
|
||||
}
|
||||
|
||||
public boolean directoryExists(String container, String directory) {
|
||||
return sync.pathExists(container + "/" + directory);
|
||||
}
|
||||
|
||||
public Blob getBlob(String container, String key,
|
||||
org.jclouds.blobstore.options.GetOptions... optionsList) {
|
||||
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
|
||||
|
@ -126,8 +133,8 @@ public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
|
|||
if (optionsList[0].isRecursive()) {
|
||||
throw new UnsupportedOperationException("recursive not currently supported in emcsaas");
|
||||
}
|
||||
if (optionsList[0].getPath() != null) {
|
||||
container = container + "/" + optionsList[0].getPath();
|
||||
if (optionsList[0].getDir() != null) {
|
||||
container = container + "/" + optionsList[0].getDir();
|
||||
}
|
||||
}
|
||||
ListOptions nativeOptions = container2ContainerListOptions.apply(optionsList);
|
||||
|
|
|
@ -118,8 +118,8 @@ public class RecursiveRemove implements ClearListStrategy, ClearContainerStrateg
|
|||
|
||||
public void execute(final String containerName, ListContainerOptions options) {
|
||||
String path = containerName;
|
||||
if (options.getPath() != null)
|
||||
path += "/" + options.getPath();
|
||||
if (options.getDir() != null)
|
||||
path += "/" + options.getDir();
|
||||
Set<Future<Void>> deletes = Sets.newHashSet();
|
||||
try {
|
||||
for (DirectoryEntry md : async.listDirectory(path).get(requestTimeoutMilliseconds,
|
||||
|
|
|
@ -197,7 +197,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient {
|
|||
container = directoryName.substring(0, directoryName.indexOf('/'));
|
||||
String path = directoryName.substring(directoryName.indexOf('/') + 1);
|
||||
if (!path.equals(""))
|
||||
options.underPath(path);
|
||||
options.inDirectory(path);
|
||||
}
|
||||
return wrapFuture(blobStore.list(container, options), resource2ObjectList);
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient {
|
|||
|
||||
public Future<Boolean> pathExists(final String path) {
|
||||
if (path.indexOf('/') == -1 || (path.endsWith("/")))
|
||||
return blobStore.exists(path);
|
||||
return blobStore.containerExists(path);
|
||||
else {
|
||||
return new FutureBase<Boolean>() {
|
||||
public Boolean get() throws InterruptedException, ExecutionException {
|
||||
|
|
|
@ -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
|
||||
application/octet-stream
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import org.jclouds.aws.ec2.EC2AsyncClient;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* "License"); you may not use this file except in compliance
|
||||
* 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,
|
||||
* software distributed under the License is distributed on an
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* "License"); you may not use this file except in compliance
|
||||
* 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,
|
||||
* software distributed under the License is distributed on an
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* "License"); you may not use this file except in compliance
|
||||
* 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,
|
||||
* software distributed under the License is distributed on an
|
||||
|
|
|
@ -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_SESSIONINTERVAL;
|
||||
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.util.Properties;
|
||||
|
@ -50,6 +52,7 @@ public class S3PropertiesBuilder extends HttpPropertiesBuilder {
|
|||
properties.setProperty(PROPERTY_S3_ENDPOINT, "https://s3.amazonaws.com");
|
||||
properties.setProperty(PROPERTY_S3_METADATA_PREFIX, "x-amz-meta-");
|
||||
properties.setProperty(PROPERTY_S3_SESSIONINTERVAL, "60");
|
||||
properties.setProperty(PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX, DIRECTORY_SUFFIX_FOLDER);
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.jclouds.aws.s3.domain.ObjectMetadata;
|
|||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.aws.s3.options.ListBucketOptions;
|
||||
import org.jclouds.blobstore.AsyncBlobStore;
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
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.options.ListContainerOptions;
|
||||
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.logging.Logger.LoggerFactory;
|
||||
|
||||
|
@ -71,11 +74,13 @@ public class S3AsyncBlobStore extends BaseS3BlobStore implements AsyncBlobStore
|
|||
ObjectToBlobMetadata object2BlobMd, ObjectToBlob object2Blob, BlobToObject blob2Object,
|
||||
ContainerToBucketListOptions container2BucketListOptions,
|
||||
BlobToObjectGetOptions blob2ObjectGetOptions,
|
||||
GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy,
|
||||
BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList,
|
||||
ExecutorService service) {
|
||||
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
org.jclouds.blobstore.options.GetOptions... optionsList) {
|
||||
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.jclouds.aws.s3.blobstore.internal.BaseS3BlobStore;
|
|||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||
import org.jclouds.aws.s3.options.ListBucketOptions;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
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.options.ListContainerOptions;
|
||||
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.logging.Logger.LoggerFactory;
|
||||
|
||||
|
@ -59,18 +62,22 @@ import com.google.common.base.Function;
|
|||
import com.google.common.collect.Iterables;
|
||||
|
||||
public class S3BlobStore extends BaseS3BlobStore implements BlobStore {
|
||||
private final S3AsyncBlobStore aBlobStore;
|
||||
|
||||
@Inject
|
||||
public S3BlobStore(S3AsyncClient async, S3Client sync, Factory blobFactory,
|
||||
LoggerFactory logFactory, ClearListStrategy clearContainerStrategy,
|
||||
ObjectToBlobMetadata object2BlobMd, ObjectToBlob object2Blob, BlobToObject blob2Object,
|
||||
public S3BlobStore(S3AsyncBlobStore aBlobStore, S3AsyncClient async, S3Client sync,
|
||||
Factory blobFactory, LoggerFactory logFactory,
|
||||
ClearListStrategy clearContainerStrategy, ObjectToBlobMetadata object2BlobMd,
|
||||
ObjectToBlob object2Blob, BlobToObject blob2Object,
|
||||
ContainerToBucketListOptions container2BucketListOptions,
|
||||
BlobToObjectGetOptions blob2ObjectGetOptions,
|
||||
GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy,
|
||||
BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList,
|
||||
ExecutorService service) {
|
||||
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
|
||||
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());
|
||||
}
|
||||
|
||||
public boolean containerExists(String container) {
|
||||
return sync.bucketExists(container);
|
||||
}
|
||||
|
||||
public boolean createContainer(String container) {
|
||||
return sync.putBucketIfNotExists(container);
|
||||
}
|
||||
|
@ -93,8 +104,17 @@ public class S3BlobStore extends BaseS3BlobStore implements BlobStore {
|
|||
sync.deleteBucketIfEmpty(container);
|
||||
}
|
||||
|
||||
public boolean exists(String container) {
|
||||
return sync.bucketExists(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 Blob getBlob(String container, String key,
|
||||
|
|
|
@ -52,7 +52,12 @@ public class BlobToObjectGetOptions implements
|
|||
}
|
||||
for (String range : from[0].getRanges()) {
|
||||
String[] firstLast = range.split("\\-");
|
||||
httpOptions.range(Long.parseLong(firstLast[0]), Long.parseLong(firstLast[1]));
|
||||
if (firstLast.length == 2)
|
||||
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;
|
||||
|
|
|
@ -50,7 +50,7 @@ public class BucketToContainerListOptions implements Function<ListBucketOptions[
|
|||
options.maxResults(optionsList[0].getMaxResults());
|
||||
}
|
||||
if (optionsList[0].getPrefix() != null) {
|
||||
options.underPath(optionsList[0].getPrefix());
|
||||
options.inDirectory(optionsList[0].getPrefix());
|
||||
}
|
||||
}
|
||||
return options;
|
||||
|
|
|
@ -34,15 +34,19 @@ import com.google.common.base.Function;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ContainerToBucketListOptions implements Function<ListContainerOptions[], ListBucketOptions> {
|
||||
public class ContainerToBucketListOptions implements
|
||||
Function<ListContainerOptions[], ListBucketOptions> {
|
||||
public ListBucketOptions apply(ListContainerOptions[] optionsList) {
|
||||
ListBucketOptions httpOptions = new ListBucketOptions();
|
||||
if (optionsList.length != 0) {
|
||||
if (!optionsList[0].isRecursive()) {
|
||||
httpOptions.delimiter("/");
|
||||
}
|
||||
if (optionsList[0].getPath() != null) {
|
||||
httpOptions.withPrefix(optionsList[0].getPath());
|
||||
if (optionsList[0].getDir() != null) {// TODO unit test
|
||||
String path = optionsList[0].getDir();
|
||||
if (!path.endsWith("/"))
|
||||
path = path + "/";
|
||||
httpOptions.withPrefix(path);
|
||||
}
|
||||
if (optionsList[0].getMarker() != null) {
|
||||
httpOptions.afterMarker(optionsList[0].getMarker());
|
||||
|
|
|
@ -23,12 +23,14 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
@ -37,6 +39,13 @@ import com.google.common.base.Function;
|
|||
*/
|
||||
@Singleton
|
||||
public class ObjectToBlobMetadata implements Function<ObjectMetadata, MutableBlobMetadata> {
|
||||
private final IsDirectoryStrategy isDirectoryStrategy;
|
||||
|
||||
@Inject
|
||||
public ObjectToBlobMetadata(IsDirectoryStrategy isDirectoryStrategy) {
|
||||
this.isDirectoryStrategy = isDirectoryStrategy;
|
||||
}
|
||||
|
||||
public MutableBlobMetadata apply(ObjectMetadata from) {
|
||||
MutableBlobMetadata to = new MutableBlobMetadataImpl();
|
||||
to.setContentMD5(from.getContentMD5());
|
||||
|
@ -46,8 +55,9 @@ public class ObjectToBlobMetadata implements Function<ObjectMetadata, MutableBlo
|
|||
to.setName(from.getKey());
|
||||
to.setSize(from.getSize());
|
||||
to.setType(ResourceType.BLOB);
|
||||
to.setLastModified(from.getLastModified());
|
||||
to.setUserMetadata(from.getUserMetadata());
|
||||
if (from.getContentType() != null && from.getContentType().equals("application/directory")) {
|
||||
if (isDirectoryStrategy.execute(to)) {
|
||||
to.setType(ResourceType.RELATIVE_PATH);
|
||||
}
|
||||
return to;
|
||||
|
|
|
@ -41,6 +41,8 @@ import org.jclouds.aws.s3.blobstore.functions.ObjectToBlob;
|
|||
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
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.logging.Logger.LoggerFactory;
|
||||
|
||||
|
@ -60,6 +62,8 @@ public class BaseS3BlobStore {
|
|||
protected final BucketToResourceMetadata bucket2ResourceMd;
|
||||
protected final BucketToResourceList bucket2ResourceList;
|
||||
protected final ExecutorService service;
|
||||
protected final GetDirectoryStrategy getDirectoryStrategy;
|
||||
protected final MkdirStrategy mkdirStrategy;
|
||||
|
||||
@Inject
|
||||
protected BaseS3BlobStore(S3AsyncClient async, S3Client sync, Blob.Factory blobFactory,
|
||||
|
@ -67,6 +71,7 @@ public class BaseS3BlobStore {
|
|||
ObjectToBlobMetadata object2BlobMd, ObjectToBlob object2Blob, BlobToObject blob2Object,
|
||||
ContainerToBucketListOptions container2BucketListOptions,
|
||||
BlobToObjectGetOptions blob2ObjectGetOptions,
|
||||
GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy,
|
||||
BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList,
|
||||
ExecutorService service) {
|
||||
this.async = checkNotNull(async, "async");
|
||||
|
@ -80,6 +85,9 @@ public class BaseS3BlobStore {
|
|||
this.container2BucketListOptions = checkNotNull(container2BucketListOptions,
|
||||
"container2BucketListOptions");
|
||||
this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
|
||||
this.getDirectoryStrategy = checkNotNull(getDirectoryStrategy,
|
||||
"getDirectoryStrategy");
|
||||
this.mkdirStrategy = checkNotNull(mkdirStrategy, "mkdirStrategy");
|
||||
this.bucket2ResourceMd = checkNotNull(bucket2ResourceMd, "bucket2ResourceMd");
|
||||
this.bucket2ResourceList = checkNotNull(bucket2ResourceList, "bucket2ResourceList");
|
||||
this.service = checkNotNull(service, "service");
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.executableBy;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.asType;
|
||||
|
|
|
@ -59,7 +59,7 @@ public class BlobStoreContextToContainerResult implements Function<String, Conta
|
|||
try {
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
context.getBlobStore().exists(from.getName());
|
||||
context.getBlobStore().containerExists(from.getName());
|
||||
status = ((System.currentTimeMillis() - start) + "ms");
|
||||
} catch (ContainerNotFoundException ex) {
|
||||
status = ("not found");
|
||||
|
|
|
@ -57,7 +57,7 @@ public abstract class BasePerformanceLiveTest extends
|
|||
containerCount = 1;
|
||||
}
|
||||
protected int timeoutSeconds = 15;
|
||||
protected int loopCount = 100;
|
||||
protected int loopCount = 1000;
|
||||
protected ExecutorService exec;
|
||||
protected CompletionService<Boolean> completer;
|
||||
|
||||
|
|
|
@ -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.options.ListBlobsOptions;
|
||||
import org.jclouds.blobstore.AsyncBlobStore;
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
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.options.ListContainerOptions;
|
||||
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.logging.Logger.LoggerFactory;
|
||||
|
||||
|
@ -70,12 +73,13 @@ public class AzureAsyncBlobStore extends BaseAzureBlobStore implements AsyncBlob
|
|||
ClearListStrategy clearContainerStrategy, BlobPropertiesToBlobMetadata object2BlobMd,
|
||||
AzureBlobToBlob object2Blob, BlobToAzureBlob blob2Object,
|
||||
ListOptionsToListBlobsOptions container2ContainerListOptions,
|
||||
BlobToHttpGetOptions blob2ObjectGetOptions,
|
||||
ContainerToResourceMetadata container2ResourceMd,
|
||||
BlobToHttpGetOptions blob2ObjectGetOptions, GetDirectoryStrategy getDirectoryStrategy,
|
||||
MkdirStrategy mkdirStrategy, ContainerToResourceMetadata container2ResourceMd,
|
||||
ListBlobsResponseToResourceList container2ResourceList, ExecutorService service) {
|
||||
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -151,4 +155,30 @@ public class AzureAsyncBlobStore extends BaseAzureBlobStore implements AsyncBlob
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.options.ListBlobsOptions;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
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.options.ListContainerOptions;
|
||||
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.logging.Logger.LoggerFactory;
|
||||
|
||||
|
@ -59,19 +62,22 @@ import com.google.common.base.Function;
|
|||
import com.google.common.collect.Iterables;
|
||||
|
||||
public class AzureBlobStore extends BaseAzureBlobStore implements BlobStore {
|
||||
private final AzureAsyncBlobStore aBlobStore;
|
||||
|
||||
@Inject
|
||||
public AzureBlobStore(AzureBlobAsyncClient async, AzureBlobClient sync, Factory blobFactory,
|
||||
LoggerFactory logFactory, ClearListStrategy clearContainerStrategy,
|
||||
BlobPropertiesToBlobMetadata object2BlobMd, AzureBlobToBlob object2Blob,
|
||||
BlobToAzureBlob blob2Object,
|
||||
public AzureBlobStore(AzureAsyncBlobStore aBlobStore, AzureBlobAsyncClient async,
|
||||
AzureBlobClient sync, Factory blobFactory, LoggerFactory logFactory,
|
||||
ClearListStrategy clearContainerStrategy, BlobPropertiesToBlobMetadata object2BlobMd,
|
||||
AzureBlobToBlob object2Blob, BlobToAzureBlob blob2Object,
|
||||
ListOptionsToListBlobsOptions container2ContainerListOptions,
|
||||
BlobToHttpGetOptions blob2ObjectGetOptions,
|
||||
ContainerToResourceMetadata container2ResourceMd,
|
||||
BlobToHttpGetOptions blob2ObjectGetOptions, GetDirectoryStrategy getDirectoryStrategy,
|
||||
MkdirStrategy mkdirStrategy, ContainerToResourceMetadata container2ResourceMd,
|
||||
ListBlobsResponseToResourceList container2ResourceList, ExecutorService service) {
|
||||
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,12 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.blob.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -34,6 +36,11 @@ import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
|||
@Singleton
|
||||
public class BlobPropertiesToBlobMetadata extends
|
||||
ListableBlobPropertiesToBlobMetadata<BlobProperties> {
|
||||
@Inject
|
||||
public BlobPropertiesToBlobMetadata(IsDirectoryStrategy isDirectoryStrategy) {
|
||||
super(isDirectoryStrategy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableBlobMetadata apply(BlobProperties from) {
|
||||
MutableBlobMetadata to = super.apply(from);
|
||||
|
|
|
@ -50,7 +50,7 @@ public class ListBlobsOptionsToListOptions implements Function<ListBlobsOptions[
|
|||
options.maxResults(optionsList[0].getMaxResults());
|
||||
}
|
||||
if (optionsList[0].getPrefix() != null) {
|
||||
options.underPath(optionsList[0].getPrefix());
|
||||
options.inDirectory(optionsList[0].getPrefix());
|
||||
}
|
||||
}
|
||||
return options;
|
||||
|
|
|
@ -41,8 +41,8 @@ public class ListOptionsToListBlobsOptions implements Function<ListContainerOpti
|
|||
if (!optionsList[0].isRecursive()) {
|
||||
httpOptions.delimiter("/");
|
||||
}
|
||||
if (optionsList[0].getPath() != null) {
|
||||
httpOptions.prefix(optionsList[0].getPath());
|
||||
if (optionsList[0].getDir() != null) {
|
||||
httpOptions.prefix(optionsList[0].getDir());
|
||||
}
|
||||
if (optionsList[0].getMarker() != null) {
|
||||
httpOptions.marker(optionsList[0].getMarker());
|
||||
|
|
|
@ -23,12 +23,14 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.blob.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.ListableBlobProperties;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
import org.jclouds.blobstore.strategy.IsDirectoryStrategy;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
@ -38,15 +40,23 @@ import com.google.common.base.Function;
|
|||
@Singleton
|
||||
public class ListableBlobPropertiesToBlobMetadata<T extends ListableBlobProperties> implements
|
||||
Function<T, MutableBlobMetadata> {
|
||||
private final IsDirectoryStrategy isDirectoryStrategy;
|
||||
|
||||
@Inject
|
||||
public ListableBlobPropertiesToBlobMetadata(IsDirectoryStrategy isDirectoryStrategy) {
|
||||
this.isDirectoryStrategy = isDirectoryStrategy;
|
||||
}
|
||||
|
||||
public MutableBlobMetadata apply(T from) {
|
||||
MutableBlobMetadata to = new MutableBlobMetadataImpl();
|
||||
if (from.getContentType() != null)
|
||||
to.setContentType(from.getContentType());
|
||||
to.setETag(from.getETag());
|
||||
to.setLastModified(from.getLastModified());
|
||||
to.setName(from.getName());
|
||||
to.setSize(from.getSize());
|
||||
to.setType(ResourceType.BLOB);
|
||||
if (from.getContentType() != null && from.getContentType().equals("application/directory")) {
|
||||
if (isDirectoryStrategy.execute(to)) {
|
||||
to.setType(ResourceType.RELATIVE_PATH);
|
||||
}
|
||||
return to;
|
||||
|
|
|
@ -41,6 +41,8 @@ import org.jclouds.azure.storage.blob.blobstore.functions.ListOptionsToListBlobs
|
|||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
|
||||
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.logging.Logger.LoggerFactory;
|
||||
|
||||
|
@ -60,6 +62,8 @@ public class BaseAzureBlobStore {
|
|||
protected final ContainerToResourceMetadata container2ResourceMd;
|
||||
protected final ListBlobsResponseToResourceList container2ResourceList;
|
||||
protected final ExecutorService service;
|
||||
protected final GetDirectoryStrategy getDirectoryStrategy;
|
||||
protected final MkdirStrategy mkdirStrategy;
|
||||
|
||||
@Inject
|
||||
protected BaseAzureBlobStore(AzureBlobAsyncClient async, AzureBlobClient sync,
|
||||
|
@ -68,6 +72,7 @@ public class BaseAzureBlobStore {
|
|||
AzureBlobToBlob object2Blob, BlobToAzureBlob blob2Object,
|
||||
ListOptionsToListBlobsOptions container2ContainerListOptions,
|
||||
BlobToHttpGetOptions blob2ObjectGetOptions,
|
||||
GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy,
|
||||
ContainerToResourceMetadata container2ResourceMd,
|
||||
ListBlobsResponseToResourceList container2ResourceList, ExecutorService service) {
|
||||
this.async = checkNotNull(async, "async");
|
||||
|
@ -81,6 +86,9 @@ public class BaseAzureBlobStore {
|
|||
this.container2ContainerListOptions = checkNotNull(container2ContainerListOptions,
|
||||
"container2ContainerListOptions");
|
||||
this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
|
||||
this.getDirectoryStrategy = checkNotNull(getDirectoryStrategy,
|
||||
"getDirectoryStrategy");
|
||||
this.mkdirStrategy = checkNotNull(mkdirStrategy, "mkdirStrategy");
|
||||
this.container2ResourceMd = checkNotNull(container2ResourceMd, "container2ResourceMd");
|
||||
this.container2ResourceList = checkNotNull(container2ResourceList, "container2ResourceList");
|
||||
this.service = checkNotNull(service, "service");
|
||||
|
|
|
@ -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.internal.ListableBlobPropertiesImpl;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.TreeSetListBlobsResponse;
|
||||
import org.jclouds.blobstore.internal.LocationAndCredentials;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.util.DateService;
|
||||
import org.joda.time.DateTime;
|
||||
|
@ -127,7 +128,7 @@ public class ContainerNameEnumerationResultsHandler extends
|
|||
currentContentEncoding = null;
|
||||
currentContentLanguage = null;
|
||||
} else if (qName.equals("Url")) {
|
||||
currentUrl = URI.create(currentText.toString().trim());
|
||||
currentUrl = LocationAndCredentials.parse(currentText.toString().trim()).uri;
|
||||
} else if (qName.equals("LastModified")) {
|
||||
currentLastModified = dateParser.rfc822DateParse(currentText.toString().trim());
|
||||
} else if (qName.equals("Etag")) {
|
||||
|
|
|
@ -29,6 +29,7 @@ import javax.inject.Inject;
|
|||
import org.jclouds.azure.storage.AzureStorageResponseException;
|
||||
import org.jclouds.azure.storage.domain.AzureStorageError;
|
||||
import org.jclouds.azure.storage.util.AzureStorageUtils;
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
|
@ -64,7 +65,13 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler {
|
|||
if (content.indexOf('<') >= 0) {
|
||||
AzureStorageError error = utils.parseAzureStorageErrorFromContent(command,
|
||||
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 {
|
||||
command.setException(new HttpResponseException(command, response, content));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -57,10 +57,14 @@ public interface AsyncBlobStore {
|
|||
Future<? extends ListContainerResponse<? extends ResourceMetadata>> list(String container,
|
||||
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<Void> createDirectory(String container, String directory);
|
||||
|
||||
/**
|
||||
* This will delete a container recursively.
|
||||
*
|
||||
|
|
|
@ -55,10 +55,14 @@ public interface BlobStore {
|
|||
ListContainerResponse<? extends ResourceMetadata> list(String container,
|
||||
ListContainerOptions... options);
|
||||
|
||||
boolean exists(String container);
|
||||
boolean containerExists(String container);
|
||||
|
||||
boolean directoryExists(String container, String directory);
|
||||
|
||||
boolean createContainer(String container);
|
||||
|
||||
void createDirectory(String container, String directory);
|
||||
|
||||
/**
|
||||
* This will delete a container recursively.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -52,7 +52,12 @@ public class BlobToHttpGetOptions implements
|
|||
}
|
||||
for (String range : from[0].getRanges()) {
|
||||
String[] firstLast = range.split("\\-");
|
||||
httpOptions.range(Long.parseLong(firstLast[0]), Long.parseLong(firstLast[1]));
|
||||
if (firstLast.length == 2)
|
||||
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;
|
||||
|
|
|
@ -46,8 +46,8 @@ import com.google.common.base.Function;
|
|||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpResponse, MutableBlobMetadata>,
|
||||
InvocationContext {
|
||||
public class ParseSystemAndUserMetadataFromHeaders implements
|
||||
Function<HttpResponse, MutableBlobMetadata>, InvocationContext {
|
||||
private final String metadataPrefix;
|
||||
private final DateService dateParser;
|
||||
private final Provider<MutableBlobMetadata> metadataFactory;
|
||||
|
@ -69,7 +69,7 @@ public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpRespo
|
|||
addETagTo(from, to);
|
||||
addContentMD5To(from, to);
|
||||
parseLastModifiedOrThrowException(from, to);
|
||||
setContentLengthOrThrowException(from, to);
|
||||
setContentLength(from, to);
|
||||
addUserMetadataTo(from, to);
|
||||
return to;
|
||||
}
|
||||
|
@ -85,13 +85,9 @@ public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpRespo
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setContentLengthOrThrowException(HttpResponse from, MutableBlobMetadata metadata)
|
||||
throws HttpException {
|
||||
void setContentLength(HttpResponse from, MutableBlobMetadata metadata) throws HttpException {
|
||||
String contentLength = from.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH);
|
||||
if (contentLength == null)
|
||||
throw new HttpException(HttpHeaders.CONTENT_LENGTH + " not found in headers");
|
||||
else
|
||||
metadata.setSize(Long.parseLong(contentLength));
|
||||
metadata.setSize(contentLength == null ? 0 : Long.parseLong(contentLength));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
@ -100,7 +96,7 @@ public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpRespo
|
|||
String lastModified = from.getFirstHeaderOrNull(HttpHeaders.LAST_MODIFIED);
|
||||
if (lastModified == null)
|
||||
throw new HttpException(HttpHeaders.LAST_MODIFIED + " header not present in response: "
|
||||
+ from);
|
||||
+ from.getStatusLine());
|
||||
metadata.setLastModified(dateParser.rfc822DateParse(lastModified));
|
||||
if (metadata.getLastModified() == null)
|
||||
throw new HttpException("could not parse: " + HttpHeaders.LAST_MODIFIED + ": "
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -135,12 +135,12 @@ public abstract class BaseBlobMap<V> {
|
|||
this.connection = checkNotNull(connection, "connection");
|
||||
this.containerName = checkNotNull(containerName, "container");
|
||||
this.options = options;
|
||||
if (options.getPath() == null) {
|
||||
if (options.getDir() == null) {
|
||||
prefixer = new PassThrough<String>();
|
||||
pathStripper = prefixer;
|
||||
} else {
|
||||
prefixer = new PrefixKey(options.getPath(), "/");
|
||||
pathStripper = new StripPath(options.getPath(), "/");
|
||||
prefixer = new PrefixKey(options.getDir(), "/");
|
||||
pathStripper = new StripPath(options.getDir(), "/");
|
||||
}
|
||||
|
||||
this.getAllBlobs = checkNotNull(getAllBlobs, "getAllBlobs");
|
||||
|
@ -225,7 +225,7 @@ public abstract class BaseBlobMap<V> {
|
|||
public SortedSet<? extends BlobMetadata> list() {
|
||||
SortedSet<? extends BlobMetadata> returnVal = getAllBlobMetadata.execute(containerName,
|
||||
options);
|
||||
if (options.getPath() != null) {
|
||||
if (options.getDir() != null) {
|
||||
returnVal = Sets.newTreeSet(Iterables.transform(returnVal,
|
||||
new Function<BlobMetadata, BlobMetadata>() {
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ public class BlobStoreContextImpl<A, S> extends RestContextImpl<A, S> implements
|
|||
String prefix = BlobStoreUtils.parsePrefixFromPath(path);
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
if (prefix != null)
|
||||
options.underPath(prefix);
|
||||
options.inDirectory(prefix);
|
||||
return blobMapFactory.create(container, options);
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ public class BlobStoreContextImpl<A, S> extends RestContextImpl<A, S> implements
|
|||
String prefix = BlobStoreUtils.parsePrefixFromPath(path);
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
if (prefix != null)
|
||||
options.underPath(prefix);
|
||||
options.inDirectory(prefix);
|
||||
return inputStreamMapFactory.create(container, options);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -65,6 +65,15 @@ public class GetOptions {
|
|||
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.
|
||||
* <p />
|
||||
|
|
|
@ -29,26 +29,26 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
/**
|
||||
* Contains options supported in the list container operation. <h2>
|
||||
* 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/>
|
||||
* <code>
|
||||
* import static org.jclouds.blobstore.options.ListContainerOptions.Builder.*
|
||||
* <p/>
|
||||
* 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>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ListContainerOptions extends ListOptions {
|
||||
|
||||
private String path;
|
||||
private String dir;
|
||||
|
||||
private boolean recursive;
|
||||
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
public String getDir() {
|
||||
return dir;
|
||||
}
|
||||
|
||||
public boolean isRecursive() {
|
||||
|
@ -59,9 +59,10 @@ public class ListContainerOptions extends ListOptions {
|
|||
* Returns a pseudo-directory listing.
|
||||
*
|
||||
*/
|
||||
public ListContainerOptions underPath(String path) {
|
||||
checkArgument(!recursive, "path and recursive combination currently not supported");
|
||||
this.path = checkNotNull(path, "path");
|
||||
public ListContainerOptions inDirectory(String dir) {
|
||||
checkArgument(!recursive, "dir and recursive combination currently not supported");
|
||||
this.dir = checkNotNull(dir, "dir");
|
||||
checkArgument(!dir.equals("/"), "dir must not be a slash");
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -83,7 +84,7 @@ public class ListContainerOptions extends ListOptions {
|
|||
* return a listing of all objects inside the store, recursively.
|
||||
*/
|
||||
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;
|
||||
return this;
|
||||
}
|
||||
|
@ -91,11 +92,11 @@ public class ListContainerOptions extends ListOptions {
|
|||
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();
|
||||
return options.underPath(path);
|
||||
return options.inDirectory(directory);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,6 +29,29 @@ package org.jclouds.blobstore.reference;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -28,7 +28,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.ResourceMetadata;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
/**
|
||||
|
@ -37,6 +40,26 @@ import org.jclouds.util.Utils;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
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) {
|
||||
String container = path;
|
||||
|
|
|
@ -84,7 +84,7 @@ public class GetOptions extends BaseHttpRequestOptions {
|
|||
*/
|
||||
public GetOptions startAt(long start) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
import org.jclouds.rest.internal.NamedResourceImpl;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.net.URI;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -77,6 +77,8 @@ public class Utils {
|
|||
* Web browsers do not always handle '+' characters well, use the well-supported '%20' instead.
|
||||
*/
|
||||
public static String urlEncode(String in, char... skipEncode) {
|
||||
if (isUrlEncoded(in))
|
||||
return in;
|
||||
try {
|
||||
String returnVal = URLEncoder.encode(in, "UTF-8").replaceAll("\\+", "%20").replaceAll(
|
||||
"\\*", "%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()
|
||||
.makeComputingMap(new Function<String, String>() {
|
||||
public String apply(String plain) {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -85,15 +85,15 @@ public class ParseBlobMetadataFromHeadersTest {
|
|||
HttpResponse from = new HttpResponse();
|
||||
from.getHeaders().put(HttpHeaders.CONTENT_LENGTH, "100");
|
||||
MutableBlobMetadata metadata = blobMetadataProvider.get();
|
||||
parser.setContentLengthOrThrowException(from, metadata);
|
||||
parser.setContentLength(from, metadata);
|
||||
assertEquals(metadata.getSize(), new Long(100));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = HttpException.class)
|
||||
public void testSetContentLengthException() {
|
||||
public void testSetContentLengthNoHeader() {
|
||||
HttpResponse from = new HttpResponse();
|
||||
MutableBlobMetadata metadata = blobMetadataProvider.get();
|
||||
parser.setContentLengthOrThrowException(from, metadata);
|
||||
parser.setContentLength(from, metadata);
|
||||
assertEquals(metadata.getSize(), new Long(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -25,6 +25,7 @@ package org.jclouds.blobstore.integration;
|
|||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
@ -54,6 +55,14 @@ import com.google.inject.TypeLiteral;
|
|||
*/
|
||||
public class StubBlobStoreContextBuilder extends BlobStoreContextBuilder<AsyncBlobStore, BlobStore> {
|
||||
|
||||
/**
|
||||
* This is only to have the same syntax.
|
||||
*
|
||||
*/
|
||||
public StubBlobStoreContextBuilder(Properties props) {
|
||||
this();
|
||||
}
|
||||
|
||||
public StubBlobStoreContextBuilder() {
|
||||
super(new TypeLiteral<AsyncBlobStore>() {
|
||||
}, new TypeLiteral<BlobStore>() {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -397,13 +397,13 @@ public class BaseBlobStoreIntegrationTest<A, S> {
|
|||
|
||||
protected static void deleteContainer(final BlobStoreContext<?, ?> context, final String name)
|
||||
throws InterruptedException {
|
||||
if (context.getBlobStore().exists(name)) {
|
||||
if (context.getBlobStore().containerExists(name)) {
|
||||
System.err.printf("*** deleting container %s...%n", name);
|
||||
context.getBlobStore().deleteContainer(name);
|
||||
assertConsistencyAware(context, new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
assert !context.getBlobStore().exists(name) : "container " + name
|
||||
assert !context.getBlobStore().containerExists(name) : "container " + name
|
||||
+ " still exists";
|
||||
} catch (Exception e) {
|
||||
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
|
|
|
@ -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.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 java.io.UnsupportedEncodingException;
|
||||
|
@ -47,7 +47,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
|
|||
|
||||
@Test(groups = { "integration", "live" })
|
||||
public void containerDoesntExist() {
|
||||
assert !context.getBlobStore().exists("forgetaboutit");
|
||||
assert !context.getBlobStore().containerExists("forgetaboutit");
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" })
|
||||
|
@ -112,7 +112,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
|
|||
add15UnderRoot(containerName);
|
||||
|
||||
ListContainerResponse<? extends ResourceMetadata> container = context.getBlobStore().list(
|
||||
containerName, underPath("apps/"));
|
||||
containerName, inDirectory("apps/"));
|
||||
assert !container.isTruncated();
|
||||
assertEquals(container.size(), 10);
|
||||
assertEquals(container.getPath(), "apps/");
|
||||
|
@ -141,7 +141,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
|
|||
public void containerExists() throws InterruptedException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
assert context.getBlobStore().exists(containerName);
|
||||
assert context.getBlobStore().containerExists(containerName);
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ public class BaseContainerIntegrationTest<A, S> extends BaseBlobStoreIntegration
|
|||
assertConsistencyAware(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
assert !context.getBlobStore().exists(containerName) : "container " + containerName
|
||||
assert !context.getBlobStore().containerExists(containerName) : "container " + containerName
|
||||
+ " still exists";
|
||||
} catch (Exception e) {
|
||||
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||
|
|
|
@ -41,9 +41,11 @@ import java.util.Map;
|
|||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
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.options.GetOptions;
|
||||
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.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
|
@ -103,17 +108,29 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
|
|||
private final ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs;
|
||||
protected final Blob.Factory blobProvider;
|
||||
protected final HttpGetOptionsListToGetOptions httpGetOptionsConverter;
|
||||
protected final GetDirectoryStrategy getDirectoryStrategy;
|
||||
protected final MkdirStrategy mkdirStrategy;
|
||||
private final IsDirectoryStrategy isDirectoryStrategy;
|
||||
|
||||
protected final ExecutorService service;
|
||||
|
||||
@Inject
|
||||
protected StubAsyncBlobStore(
|
||||
ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs,
|
||||
DateService dateService, Blob.Factory blobProvider,
|
||||
HttpGetOptionsListToGetOptions httpGetOptionsConverter) {
|
||||
GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy,
|
||||
IsDirectoryStrategy isDirectoryStrategy,
|
||||
HttpGetOptionsListToGetOptions httpGetOptionsConverter, ExecutorService service) {
|
||||
this.dateService = checkNotNull(dateService, "dateService");
|
||||
this.containerToBlobs = checkNotNull(containerToBlobs, "containerToBlobs");
|
||||
this.blobProvider = checkNotNull(blobProvider, "blobProvider");
|
||||
this.getDirectoryStrategy = checkNotNull(getDirectoryStrategy, "getDirectoryStrategy");
|
||||
this.mkdirStrategy = checkNotNull(mkdirStrategy, "mkdirStrategy");
|
||||
this.isDirectoryStrategy = checkNotNull(isDirectoryStrategy, "isDirectoryStrategy");
|
||||
this.httpGetOptionsConverter = checkNotNull(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
|
||||
.keySet(), new Function<String, ResourceMetadata>() {
|
||||
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);
|
||||
}
|
||||
|
||||
final String prefix = options.getPath();
|
||||
final String prefix = options.getDir();
|
||||
if (prefix != null) {
|
||||
contents = Sets.newTreeSet(Iterables.filter(contents,
|
||||
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>() {
|
||||
public Boolean get() throws InterruptedException, ExecutionException {
|
||||
return getContainerToBlobs().containsKey(container);
|
||||
|
@ -490,9 +510,10 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
|
|||
new RuntimeException("bucketName not found: " + bucketName);
|
||||
}
|
||||
try {
|
||||
byte[] data = toByteArray(object.getData());
|
||||
object.getMetadata().setSize(data.length);
|
||||
MutableBlobMetadata newMd = copy(object.getMetadata());
|
||||
newMd.setLastModified(new DateTime());
|
||||
byte[] data = toByteArray(object.getData());
|
||||
final byte[] md5 = HttpUtils.md5(data);
|
||||
final String eTag = HttpUtils.toHexString(md5);
|
||||
newMd.setETag(eTag);
|
||||
|
@ -573,10 +594,10 @@ public class StubAsyncBlobStore implements AsyncBlobStore {
|
|||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
for (String s : options.getRanges()) {
|
||||
if (s.startsWith("-")) {
|
||||
int length = Integer.parseInt(s);
|
||||
int length = Integer.parseInt(s.substring(1));
|
||||
out.write(data, data.length - length, length);
|
||||
} 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);
|
||||
} else if (s.contains("-")) {
|
||||
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() {
|
||||
return blobProvider.create(null);
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
|
||||
}
|
||||
}
|
|
@ -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.maxResults;
|
||||
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.assertTrue;
|
||||
|
||||
|
@ -54,21 +54,21 @@ public class ListOptionsTest {
|
|||
@Test
|
||||
public void testPath() {
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
options.underPath("test");
|
||||
assertEquals(options.getPath(), "test");
|
||||
options.inDirectory("test");
|
||||
assertEquals(options.getDir(), "test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPathStatic() {
|
||||
ListContainerOptions options = underPath("test");
|
||||
assertEquals(options.getPath(), "test");
|
||||
ListContainerOptions options = inDirectory("test");
|
||||
assertEquals(options.getDir(), "test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoOptions() {
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
options.underPath("test").maxResults(1);
|
||||
assertEquals(options.getPath(), "test");
|
||||
options.inDirectory("test").maxResults(1);
|
||||
assertEquals(options.getDir(), "test");
|
||||
assertEquals(options.getMaxResults(), new Integer(1));
|
||||
|
||||
}
|
||||
|
@ -76,12 +76,12 @@ public class ListOptionsTest {
|
|||
@Test
|
||||
public void testNullPath() {
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
assertEquals(options.getPath(), null);
|
||||
assertEquals(options.getDir(), null);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testPathNPE() {
|
||||
underPath(null);
|
||||
inDirectory(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import com.google.common.base.Service;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import com.google.common.base.Service;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
/**
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue