Merge branch 'master' into hpcloud-object-storage

This commit is contained in:
Jeremy Daggett 2011-12-19 14:47:07 -08:00
commit 6d6d68fdde
48 changed files with 2582 additions and 19 deletions

View File

@ -100,5 +100,10 @@
<artifactId>filesystem</artifactId> <artifactId>filesystem</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.jclouds.provider</groupId>
<artifactId>hpcloud-object-storage</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -18,6 +18,11 @@
*/ */
package org.jclouds.openstack.swift.domain; package org.jclouds.openstack.swift.domain;
import java.util.Map;
import com.google.common.collect.Maps;
import com.google.gson.annotations.SerializedName;
/** /**
* *
@ -28,14 +33,20 @@ public class ContainerMetadata implements Comparable<ContainerMetadata> {
private String name; private String name;
private long count; private long count;
private long bytes; private long bytes;
@SerializedName("X-Container-Read")
private String readACL;
private Map<String, String> metadata = Maps.newLinkedHashMap();
public ContainerMetadata() { public ContainerMetadata() {
} }
public ContainerMetadata(String name, long count, long bytes) { public ContainerMetadata(String name, long count, long bytes, String readACL, Map<String, String> metadata) {
setName(name); this.name = name;
setBytes(bytes); this.count = count;
setCount(count); this.bytes = bytes;
this.readACL = readACL;
this.metadata = metadata;
} }
public long getCount() { public long getCount() {
@ -46,20 +57,35 @@ public class ContainerMetadata implements Comparable<ContainerMetadata> {
this.count = count; this.count = count;
} }
public String getName() {
return name;
}
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
public String getName() { public long getBytes() {
return name; return bytes;
} }
public void setBytes(long bytes) { public void setBytes(long bytes) {
this.bytes = bytes; this.bytes = bytes;
} }
public long getBytes() { public boolean isPublic() {
return bytes; if (readACL == null)
return false;
return readACL.equals(".r:*,.rlistings");
}
public void setReadACL(String readACL) {
this.readACL = readACL;
}
public Map<String, String> getMetadata() {
return metadata;
} }
@Override @Override
@ -99,4 +125,10 @@ public class ContainerMetadata implements Comparable<ContainerMetadata> {
return (this == o) ? 0 : getName().compareTo(o.getName()); return (this == o) ? 0 : getName().compareTo(o.getName());
} }
@Override
public String toString() {
return "ContainerMetadata [name=" + name + ", count=" + count + ", bytes="
+ bytes + ", isPublic=" + isPublic() + "]";
}
} }

View File

@ -28,5 +28,10 @@ public interface SwiftHeaders {
public static final String ACCOUNT_CONTAINER_COUNT = "X-Account-Container-Count"; public static final String ACCOUNT_CONTAINER_COUNT = "X-Account-Container-Count";
public static final String CONTAINER_BYTES_USED = "X-Container-Bytes-Used"; public static final String CONTAINER_BYTES_USED = "X-Container-Bytes-Used";
public static final String CONTAINER_OBJECT_COUNT = "X-Container-Object-Count"; public static final String CONTAINER_OBJECT_COUNT = "X-Container-Object-Count";
public static final String CONTAINER_METADATA_PREFIX = "X-Container-Meta-";
public static final String USER_METADATA_PREFIX = "X-Object-Meta-"; public static final String USER_METADATA_PREFIX = "X-Object-Meta-";
public static final String CONTAINER_READ = "X-Container-Read";
public static final String CONTAINER_WRITE = "X-Container-Write";
} }

View File

@ -21,7 +21,9 @@ package org.jclouds.openstack.swift.functions;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseJson; import org.jclouds.http.functions.ParseJson;
@ -50,9 +52,10 @@ public class ParseContainerListFromJsonResponseTest {
public void testApplyInputStream() { public void testApplyInputStream() {
InputStream is = Strings2 InputStream is = Strings2
.toInputStream("[ {\"name\":\"test_container_1\",\"count\":2,\"bytes\":78}, {\"name\":\"test_container_2\",\"count\":1,\"bytes\":17} ] "); .toInputStream("[ {\"name\":\"test_container_1\",\"count\":2,\"bytes\":78}, {\"name\":\"test_container_2\",\"count\":1,\"bytes\":17} ] ");
Map<String, String> meta = new HashMap<String, String>();
List<ContainerMetadata> expects = ImmutableList.of(new ContainerMetadata("test_container_1", 2, 78), List<ContainerMetadata> expects = ImmutableList.of(new ContainerMetadata("test_container_1", 2, 78, null, meta),
new ContainerMetadata("test_container_2", 1, 17)); new ContainerMetadata("test_container_2", 1, 17, null, meta));
ParseJson<List<ContainerMetadata>> parser = i.getInstance(Key ParseJson<List<ContainerMetadata>> parser = i.getInstance(Key
.get(new TypeLiteral<ParseJson<List<ContainerMetadata>>>() { .get(new TypeLiteral<ParseJson<List<ContainerMetadata>>>() {
})); }));

View File

@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.util.concurrent.Futures.immediateFuture; import static com.google.common.util.concurrent.Futures.immediateFuture;
import java.net.URI; import java.net.URI;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
@ -41,6 +42,7 @@ import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.concurrent.Futures; import org.jclouds.concurrent.Futures;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.jclouds.openstack.swift.CommonSwiftAsyncClient; import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
import org.jclouds.openstack.swift.SwiftAsyncClient;
import org.jclouds.openstack.swift.blobstore.functions.BlobToObject; import org.jclouds.openstack.swift.blobstore.functions.BlobToObject;
import org.jclouds.openstack.swift.blobstore.functions.ListContainerOptionsToBlobStoreListContainerOptions; import org.jclouds.openstack.swift.blobstore.functions.ListContainerOptionsToBlobStoreListContainerOptions;
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlob; import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlob;
@ -146,7 +148,7 @@ public class StubSwiftAsyncClient implements CommonSwiftAsyncClient {
return immediateFuture(Sets.newHashSet(Iterables.transform(blobStore.getContainerToBlobs().keySet(), return immediateFuture(Sets.newHashSet(Iterables.transform(blobStore.getContainerToBlobs().keySet(),
new Function<String, ContainerMetadata>() { new Function<String, ContainerMetadata>() {
public ContainerMetadata apply(String name) { public ContainerMetadata apply(String name) {
return new ContainerMetadata(name, -1, -1); return new ContainerMetadata(name, -1, -1, null, new HashMap<String,String>());
} }
}))); })));
} }

View File

@ -228,3 +228,9 @@ virtualbox.propertiesbuilder=org.jclouds.virtualbox.VirtualBoxPropertiesBuilder
filesystem.contextbuilder=org.jclouds.filesystem.FilesystemBlobStoreContextBuilder filesystem.contextbuilder=org.jclouds.filesystem.FilesystemBlobStoreContextBuilder
filesystem.propertiesbuilder=org.jclouds.filesystem.FilesystemBlobStorePropertiesBuilder filesystem.propertiesbuilder=org.jclouds.filesystem.FilesystemBlobStorePropertiesBuilder
hpcloud-compute.contextbuilder=org.jclouds.hpcloud.compute.HPCloudComputeContextBuilder
hpcloud-compute.propertiesbuilder=org.jclouds.hpcloud.compute.HPCloudComputePropertiesBuilder
hpcloud-object-storage.contextbuilder=org.jclouds.hpcloud.object.storage.HPCloudObjectStorageContextBuilder
hpcloud-object-storage.propertiesbuilder=org.jclouds.hpcloud.object.storage.HPCloudObjectStoragePropertiesBuilder

View File

@ -0,0 +1,25 @@
====
Licensed to jclouds, Inc. (jclouds) under one or more
contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. jclouds licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
====
#
# The jclouds API for HP Cloud Object Storage (https://manage.hpcloud.com/pages/build/docs/object-storage/overview).
#
# TODO: Implementation status.
# TODO: Supported features.
# TODO: Usage example.

View File

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to jclouds, Inc. (jclouds) under one or more
contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. jclouds licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
<version>1.3.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.jclouds.provider</groupId>
<artifactId>hpcloud-object-storage</artifactId>
<name>jclouds HP Cloud Object Storage</name>
<description>jclouds components to access HP Cloud Services Object Storage</description>
<packaging>bundle</packaging>
<properties>
<test.initializer>org.jclouds.hpcloud.object.storage.blobstore.integration.HPCloudObjectStorageTestInitializer</test.initializer>
<test.hpcloud-object-storage.endpoint>${test.hpcloud-object-storage.endpoint}</test.hpcloud-object-storage.endpoint>
<test.hpcloud-object-storage.apiversion>1.1</test.hpcloud-object-storage.apiversion>
<test.hpcloud-object-storage.identity>${test.hpcloud-object-storage.identity}</test.hpcloud-object-storage.identity>
<test.hpcloud-object-storage.credential>${test.hpcloud-object-storage.credential}</test.hpcloud-object-storage.credential>
</properties>
<dependencies>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>swift</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.common</groupId>
<artifactId>openstack-common</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-blobstore</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>swift</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-log4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemProperties>
<property>
<name>test.hpcloud-object-storage.endpoint</name>
<value>${test.hpcloud-object-storage.endpoint}</value>
</property>
<property>
<name>test.hpcloud-object-storage.apiversion</name>
<value>${test.hpcloud-object-storage.apiversion}</value>
</property>
<property>
<name>test.hpcloud-object-storage.identity</name>
<value>${test.hpcloud-object-storage.identity}</value>
</property>
<property>
<name>test.hpcloud-object-storage.credential</name>
<value>${test.hpcloud-object-storage.credential}</value>
</property>
<property>
<name>test.initializer</name>
<value>${test.initializer}</value>
</property>
<property>
<name>jclouds.blobstore.httpstream.url</name>
<value>${jclouds.blobstore.httpstream.url}</value>
</property>
<property>
<name>jclouds.blobstore.httpstream.md5</name>
<value>${jclouds.blobstore.httpstream.md5}</value>
</property>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Export-Package>org.jclouds.hpcloud.object.storage.*;version="${project.version}"</Export-Package>
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,40 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
* Represents a component related to HP Cloud Services Content Delivery Network.
*
* @see <a href="https://manage.hpcloud.com/pages/build/docs/object-storage/api">HP Cloud Object Storage API</a>
* @author Jeremy Daggett
*
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Qualifier
public @interface CDNManagement {
}

View File

@ -0,0 +1,150 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage;
import java.net.URI;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.blobstore.functions.ReturnNullOnContainerNotFound;
import org.jclouds.hpcloud.object.storage.domain.ContainerCDNMetadata;
import org.jclouds.hpcloud.object.storage.functions.ParseCDNUriFromHeaders;
import org.jclouds.hpcloud.object.storage.functions.ParseContainerCDNMetadataFromHeaders;
import org.jclouds.hpcloud.object.storage.functions.ParseContainerMetadataFromHeaders;
import org.jclouds.hpcloud.object.storage.options.CreateContainerOptions;
import org.jclouds.hpcloud.object.storage.options.ListCDNContainerOptions;
import org.jclouds.hpcloud.object.storage.reference.HPCloudObjectStorageHeaders;
import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
import org.jclouds.openstack.swift.Storage;
import org.jclouds.openstack.swift.domain.ContainerMetadata;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SkipEncoding;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to HP Cloud Object Storage via the REST API.
*
* <p/>All commands return a ListenableFuture of the result. Any exceptions incurred
* during processing will be wrapped in an {@link ExecutionException} as documented in
* {@link ListenableFuture#get()}.
*
* @see HPCloudObjectStorageClient
* @see <a href="https://manage.hpcloud.com/pages/build/docs/object-storage/api">HP Cloud Object Storage API</a>
* @author Jeremy Daggett
*/
@SkipEncoding('/')
@RequestFilters(AuthenticateRequest.class)
@Endpoint(Storage.class)
public interface HPCloudObjectStorageAsyncClient extends CommonSwiftAsyncClient {
/**
* @see HPCloudObjectStorageClient#listCDNContainers(ListCDNContainerOptions)
*/
@GET
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/")
@Endpoint(CDNManagement.class)
ListenableFuture<? extends Set<ContainerCDNMetadata>> listCDNContainers(ListCDNContainerOptions... options);
/**
* @see HPCloudObjectStorageClient#getCDNMetadata(String)
*/
@HEAD
@ResponseParser(ParseContainerCDNMetadataFromHeaders.class)
@ExceptionParser(ReturnNullOnContainerNotFound.class)
@Path("/{container}")
@Endpoint(CDNManagement.class)
ListenableFuture<ContainerCDNMetadata> getCDNMetadata(@PathParam("container") String container);
/**
* @see HPCloudObjectStorageClient#getCDNMetadata(String)
*/
@HEAD
@ResponseParser(ParseContainerMetadataFromHeaders.class)
@ExceptionParser(ReturnNullOnContainerNotFound.class)
@Path("/{container}")
ListenableFuture<ContainerMetadata> getContainerMetadata(@PathParam("container") String container);
/**
* @see HPCloudObjectStorageClient#createContainer
*/
@PUT
@Path("/{container}")
ListenableFuture<Boolean> createContainer(@PathParam("container") String container,
CreateContainerOptions... options);
/**
* @see HPCloudObjectStorageClient#enableCDN(String, long)
*/
@PUT
@Path("/{container}")
@Headers(keys = HPCloudObjectStorageHeaders.CDN_ENABLED, values = "True")
@ResponseParser(ParseCDNUriFromHeaders.class)
@Endpoint(CDNManagement.class)
ListenableFuture<URI> enableCDN(@PathParam("container") String container,
@HeaderParam(HPCloudObjectStorageHeaders.CDN_TTL) long ttl);
/**
* @see HPCloudObjectStorageClient#enableCDN(String)
*/
@PUT
@Path("/{container}")
@Headers(keys = HPCloudObjectStorageHeaders.CDN_ENABLED, values = "True")
@ResponseParser(ParseCDNUriFromHeaders.class)
@Endpoint(CDNManagement.class)
ListenableFuture<URI> enableCDN(@PathParam("container") String container);
/**
* @see HPCloudObjectStorageClient#updateCDN(String, long)
*/
@POST
@Path("/{container}")
@ResponseParser(ParseCDNUriFromHeaders.class)
@Endpoint(CDNManagement.class)
ListenableFuture<URI> updateCDN(@PathParam("container") String container,
@HeaderParam(HPCloudObjectStorageHeaders.CDN_TTL) long ttl);
/**
* @see HPCloudObjectStorageClient#disableCDN(String)
*/
@PUT
@Path("/{container}")
@Headers(keys = HPCloudObjectStorageHeaders.CDN_ENABLED, values = "False")
@Endpoint(CDNManagement.class)
ListenableFuture<Boolean> disableCDN(@PathParam("container") String container);
}

View File

@ -0,0 +1,65 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage;
import java.net.URI;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.hpcloud.object.storage.domain.ContainerCDNMetadata;
import org.jclouds.hpcloud.object.storage.options.CreateContainerOptions;
import org.jclouds.hpcloud.object.storage.options.ListCDNContainerOptions;
import org.jclouds.openstack.swift.CommonSwiftClient;
import org.jclouds.openstack.swift.domain.ContainerMetadata;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides synchronous access to HP Cloud Object Storage via the REST API.
*
* <p/>All commands return a ListenableFuture of the result. Any exceptions incurred
* during processing will be wrapped in an {@link ExecutionException} as documented in
* {@link ListenableFuture#get()}.
*
* @see HPCloudObjectStorageClient
* @see <a href="https://manage.hpcloud.com/pages/build/docs/object-storage/api">HP Cloud Object Storage API</a>
* @author Jeremy Daggett
*/
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
public interface HPCloudObjectStorageClient extends CommonSwiftClient {
boolean createContainer(String container, CreateContainerOptions... options);
Set<ContainerCDNMetadata> listCDNContainers(ListCDNContainerOptions... options);
ContainerCDNMetadata getCDNMetadata(String container);
ContainerMetadata getContainerMetadata(String container);
URI enableCDN(String container, long ttl);
URI enableCDN(String container);
URI updateCDN(String container, long ttl);
boolean disableCDN(String container);
}

View File

@ -0,0 +1,61 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage;
import java.util.List;
import java.util.Properties;
import org.jclouds.blobstore.BlobStoreContextBuilder;
import org.jclouds.hpcloud.object.storage.blobstore.config.HPCloudObjectStorageBlobStoreContextModule;
import org.jclouds.hpcloud.object.storage.config.HPCloudObjectStorageRestClientModule;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import com.google.inject.Injector;
import com.google.inject.Module;
/**
* Creates {@link HPCloudObjectStorageBlobStore} or {@link Injector} instances based on the most
* commonly requested arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole, Andrew Newdigate
* @see HPCloudObjectStorageBlobStore
*/
public class HPCloudObjectStorageContextBuilder extends BlobStoreContextBuilder<HPCloudObjectStorageClient, HPCloudObjectStorageAsyncClient> {
public HPCloudObjectStorageContextBuilder(Properties props) {
super(HPCloudObjectStorageClient.class, HPCloudObjectStorageAsyncClient.class, props);
}
@Override
protected void addContextModule(List<Module> modules) {
modules.add(new HPCloudObjectStorageBlobStoreContextModule());
}
@Override
protected void addClientModule(List<Module> modules) {
modules.add(new HPCloudObjectStorageRestClientModule());
}
}

View File

@ -0,0 +1,55 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.Constants.PROPERTY_ISO3166_CODES;
import static org.jclouds.hpcloud.object.storage.reference.HPCloudObjectStorageConstants.PROPERTY_CDN_ENDPOINT;
import java.util.Properties;
import org.jclouds.openstack.OpenStackAuthAsyncClient;
import org.jclouds.openstack.swift.SwiftPropertiesBuilder;
/**
* @author Jeremy Daggett
*/
public class HPCloudObjectStoragePropertiesBuilder extends SwiftPropertiesBuilder {
public HPCloudObjectStoragePropertiesBuilder(Properties properties) {
super(properties);
}
@Override
protected Properties defaultProperties() {
Properties properties = super.defaultProperties();
properties.setProperty(PROPERTY_ISO3166_CODES, "US-NV");
properties.setProperty(PROPERTY_ENDPOINT, "https://region-a.geo-1.objects.hpcloudsvc.com/auth/");
properties.setProperty(PROPERTY_API_VERSION, OpenStackAuthAsyncClient.VERSION);
properties.setProperty(PROPERTY_CDN_ENDPOINT, "https://region-a.geo-1.cdnmgmt.hpcloudsvc.com");
return properties;
}
protected HPCloudObjectStoragePropertiesBuilder withCDNEndpoint(String endpoint) {
properties.setProperty(PROPERTY_CDN_ENDPOINT, endpoint);
return this;
}
}

View File

@ -0,0 +1,116 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage;
import com.google.common.collect.ImmutableSet;
import java.net.URI;
import java.util.Set;
import org.jclouds.providers.BaseProviderMetadata;
import org.jclouds.providers.ProviderMetadata;
/**
* Implementation of {@link org.jclouds.providers.ProviderMetadata} for HP Cloud Services Object Storage
*
* @author Jeremy Daggett
*/
public class HPCloudObjectStorageProviderMetadata extends BaseProviderMetadata {
/**
* {@inheritDoc}
*/
@Override
public String getId() {
return "hpcloud-object-storage";
}
/**
* {@inheritDoc}
*/
@Override
public String getType() {
return ProviderMetadata.BLOBSTORE_TYPE;
}
/**
* {@inheritDoc}
*/
@Override
public String getName() {
return "HP Cloud Services Object Storage";
}
/**
* {@inheritDoc}
*/
@Override
public String getIdentityName() {
return "Account ID";
}
/**
* {@inheritDoc}
*/
@Override
public String getCredentialName() {
return "Access Key";
}
/**
* {@inheritDoc}
*/
@Override
public URI getHomepage() {
return URI.create("http://hpcloud.com");
}
/**
* {@inheritDoc}
*/
@Override
public URI getConsole() {
return URI.create("https://manage.hpcloud.com/objects/us-west");
}
/**
* {@inheritDoc}
*/
@Override
public URI getApiDocumentation() {
return URI.create("https://manage.hpcloud.com/pages/build/docs/object-storage/api");
}
/**
* {@inheritDoc}
*/
@Override
public Set<String> getLinkedServices() {
return ImmutableSet.of("hpcloud-object-storage");
}
/**
* {@inheritDoc}
*/
@Override
public Set<String> getIso3166Codes() {
return ImmutableSet.of("US-NV");
}
}

View File

@ -0,0 +1,95 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata;
import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized;
import org.jclouds.concurrent.Futures;
import org.jclouds.domain.Location;
import org.jclouds.hpcloud.object.storage.HPCloudObjectStorageAsyncClient;
import org.jclouds.hpcloud.object.storage.HPCloudObjectStorageClient;
import org.jclouds.hpcloud.object.storage.blobstore.functions.EnableCDNAndCache;
import org.jclouds.openstack.swift.blobstore.SwiftAsyncBlobStore;
import org.jclouds.openstack.swift.blobstore.functions.BlobStoreListContainerOptionsToListContainerOptions;
import org.jclouds.openstack.swift.blobstore.functions.BlobToObject;
import org.jclouds.openstack.swift.blobstore.functions.ContainerToResourceList;
import org.jclouds.openstack.swift.blobstore.functions.ContainerToResourceMetadata;
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlob;
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlobMetadata;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.util.concurrent.ListenableFuture;
/**
*
* @author Adrian Cole
*/
@Singleton
public class HPCloudObjectStorageAsyncBlobStore extends SwiftAsyncBlobStore {
private final EnableCDNAndCache enableCDNAndCache;
@Inject
protected HPCloudObjectStorageAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier<Location> defaultLocation,
@Memoized Supplier<Set<? extends Location>> locations, HPCloudObjectStorageClient sync, HPCloudObjectStorageAsyncClient async,
ContainerToResourceMetadata container2ResourceMd,
BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions,
ContainerToResourceList container2ResourceList, ObjectToBlob object2Blob, BlobToObject blob2Object,
ObjectToBlobMetadata object2BlobMd, BlobToHttpGetOptions blob2ObjectGetOptions,
Provider<FetchBlobMetadata> fetchBlobMetadataProvider, EnableCDNAndCache enableCDNAndCache) {
super(context, blobUtils, service, defaultLocation, locations, sync, async, container2ResourceMd,
container2ContainerListOptions, container2ResourceList, object2Blob, blob2Object, object2BlobMd,
blob2ObjectGetOptions, fetchBlobMetadataProvider);
this.enableCDNAndCache = enableCDNAndCache;
}
@Override
public ListenableFuture<Boolean> createContainerInLocation(Location location, final String container,
CreateContainerOptions options) {
ListenableFuture<Boolean> returnVal = createContainerInLocation(location, container);
if (options.isPublicRead())
return Futures.compose(createContainerInLocation(location, container), new Function<Boolean, Boolean>() {
@Override
public Boolean apply(Boolean input) {
if (Boolean.TRUE.equals(input)) {
return enableCDNAndCache.apply(container) != null;
}
return false;
}
}, service);
return returnVal;
}
}

View File

@ -0,0 +1,79 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata;
import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location;
import org.jclouds.hpcloud.object.storage.blobstore.functions.EnableCDNAndCache;
import org.jclouds.openstack.swift.CommonSwiftClient;
import org.jclouds.openstack.swift.blobstore.SwiftBlobStore;
import org.jclouds.openstack.swift.blobstore.functions.BlobStoreListContainerOptionsToListContainerOptions;
import org.jclouds.openstack.swift.blobstore.functions.BlobToObject;
import org.jclouds.openstack.swift.blobstore.functions.ContainerToResourceList;
import org.jclouds.openstack.swift.blobstore.functions.ContainerToResourceMetadata;
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlob;
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlobMetadata;
import com.google.common.base.Supplier;
/**
*
* @author Adrian Cole
*/
@Singleton
public class HPCloudObjectStorageBlobStore extends SwiftBlobStore {
private EnableCDNAndCache enableCDNAndCache;
@Inject
protected HPCloudObjectStorageBlobStore(BlobStoreContext context, BlobUtils blobUtils, Supplier<Location> defaultLocation,
@Memoized Supplier<Set<? extends Location>> locations, CommonSwiftClient sync,
ContainerToResourceMetadata container2ResourceMd,
BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions,
ContainerToResourceList container2ResourceList, ObjectToBlob object2Blob, BlobToObject blob2Object,
ObjectToBlobMetadata object2BlobMd, BlobToHttpGetOptions blob2ObjectGetOptions,
Provider<FetchBlobMetadata> fetchBlobMetadataProvider, EnableCDNAndCache enableCDNAndCache) {
super(context, blobUtils, defaultLocation, locations, sync, container2ResourceMd, container2ContainerListOptions,
container2ResourceList, object2Blob, blob2Object, object2BlobMd, blob2ObjectGetOptions,
fetchBlobMetadataProvider);
this.enableCDNAndCache = enableCDNAndCache;
}
@Override
public boolean createContainerInLocation(Location location, String container, CreateContainerOptions options) {
try {
return createContainerInLocation(location, container);
} finally {
if (options.isPublicRead())
enableCDNAndCache.apply(container);
}
}
}

View File

@ -0,0 +1,70 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.config;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.inject.Singleton;
import org.jclouds.hpcloud.object.storage.HPCloudObjectStorageClient;
import org.jclouds.hpcloud.object.storage.blobstore.HPCloudObjectStorageAsyncBlobStore;
import org.jclouds.hpcloud.object.storage.blobstore.HPCloudObjectStorageBlobStore;
import org.jclouds.hpcloud.object.storage.blobstore.functions.HPCloudObjectStorageObjectToBlobMetadata;
import org.jclouds.hpcloud.object.storage.domain.ContainerCDNMetadata;
import org.jclouds.openstack.swift.blobstore.SwiftAsyncBlobStore;
import org.jclouds.openstack.swift.blobstore.SwiftBlobStore;
import org.jclouds.openstack.swift.blobstore.config.SwiftBlobStoreContextModule;
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlobMetadata;
import com.google.common.base.Function;
import com.google.common.collect.MapMaker;
import com.google.inject.Provides;
/**
*
* @author Adrian Cole
*/
public class HPCloudObjectStorageBlobStoreContextModule extends SwiftBlobStoreContextModule {
@Provides
@Singleton
protected Map<String, URI> cdnContainer(final HPCloudObjectStorageClient client) {
return new MapMaker().expireAfterWrite(30, TimeUnit.SECONDS).makeComputingMap(new Function<String, URI>() {
public URI apply(String container) {
ContainerCDNMetadata md = client.getCDNMetadata(container);
return md != null ? md.getCDNUri() : null;
}
@Override
public String toString() {
return "getCDNMetadata()";
}
});
}
@Override
protected void configure() {
super.configure();
bind(SwiftBlobStore.class).to(HPCloudObjectStorageBlobStore.class);
bind(SwiftAsyncBlobStore.class).to(HPCloudObjectStorageAsyncBlobStore.class);
bind(ObjectToBlobMetadata.class).to(HPCloudObjectStorageObjectToBlobMetadata.class);
}
}

View File

@ -0,0 +1,53 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.functions;
import java.net.URI;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.hpcloud.object.storage.HPCloudObjectStorageClient;
import com.google.common.base.Function;
/**
*
* @author Adrian Cole
*/
@Singleton
public class EnableCDNAndCache implements Function<String, URI> {
private final Map<String, URI> cdnContainer;
private final HPCloudObjectStorageClient sync;
@Inject
public EnableCDNAndCache(HPCloudObjectStorageClient sync, Map<String, URI> cdnContainer) {
this.sync = sync;
this.cdnContainer = cdnContainer;
}
@Override
public URI apply(String input) {
URI uri = sync.enableCDN(input);
cdnContainer.put(input, uri);
return uri;
}
}

View File

@ -0,0 +1,50 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.functions;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.strategy.IfDirectoryReturnNameStrategy;
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlobMetadata;
import org.jclouds.openstack.swift.domain.ObjectInfo;
/**
* @author Adrian Cole
*/
@Singleton
public class HPCloudObjectStorageObjectToBlobMetadata extends ObjectToBlobMetadata {
private final PublicUriForObjectInfo publicUriForObjectInfo;
@Inject
public HPCloudObjectStorageObjectToBlobMetadata(IfDirectoryReturnNameStrategy ifDirectoryReturnName,
PublicUriForObjectInfo publicUriForObjectInfo) {
super(ifDirectoryReturnName);
this.publicUriForObjectInfo = publicUriForObjectInfo;
}
public MutableBlobMetadata apply(ObjectInfo from) {
if (from == null)
return null;
MutableBlobMetadata to = super.apply(from);
to.setPublicUri(publicUriForObjectInfo.apply(from));
return to;
}
}

View File

@ -0,0 +1,58 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.functions;
import java.net.URI;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
import org.jclouds.openstack.swift.domain.ObjectInfo;
import com.google.common.base.Function;
/**
* @author Adrian Cole
*/
@Singleton
public class PublicUriForObjectInfo implements Function<ObjectInfo, URI> {
private final Map<String, URI> cdnContainer;
private final Provider<UriBuilder> uriBuilders;
@Inject
public PublicUriForObjectInfo(Map<String, URI> cdnContainer, Provider<UriBuilder> uriBuilders) {
this.cdnContainer = cdnContainer;
this.uriBuilders = uriBuilders;
}
public URI apply(ObjectInfo from) {
if (from == null)
return null;
try {
return uriBuilders.get().uri(cdnContainer.get(from.getContainer())).path(from.getName()).replaceQuery("")
.build();
} catch (NullPointerException e) {
// MapMaker constructed maps are not allowed to return null;
return null;
}
}
}

View File

@ -0,0 +1,76 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.config;
import static org.jclouds.hpcloud.object.storage.reference.HPCloudObjectStorageConstants.PROPERTY_CDN_ENDPOINT;
import java.net.URI;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.hpcloud.object.storage.CDNManagement;
import org.jclouds.hpcloud.object.storage.HPCloudObjectStorageAsyncClient;
import org.jclouds.hpcloud.object.storage.HPCloudObjectStorageClient;
import org.jclouds.http.RequiresHttp;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
import org.jclouds.openstack.reference.AuthHeaders;
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
import org.jclouds.openstack.swift.CommonSwiftClient;
import org.jclouds.openstack.swift.config.BaseSwiftRestClientModule;
import org.jclouds.rest.ConfiguresRestClient;
import com.google.inject.Provides;
/**
*
* @author Adrian Cole
*/
@ConfiguresRestClient
@RequiresHttp
public class HPCloudObjectStorageRestClientModule extends BaseSwiftRestClientModule<HPCloudObjectStorageClient, HPCloudObjectStorageAsyncClient> {
public HPCloudObjectStorageRestClientModule() {
super(HPCloudObjectStorageClient.class, HPCloudObjectStorageAsyncClient.class);
}
@Provides
@Singleton
CommonSwiftClient provideCommonSwiftClient(HPCloudObjectStorageClient in) {
return in;
}
@Provides
@Singleton
CommonSwiftAsyncClient provideCommonSwiftClient(HPCloudObjectStorageAsyncClient in) {
return in;
}
@Provides
@Singleton
@CDNManagement
protected URI provideCDNUrl(AuthenticationResponse response, @Named(PROPERTY_CDN_ENDPOINT) String cdnEndpoint) {
if (response.getServices().get(AuthHeaders.CDN_MANAGEMENT_URL) == null) {
return URI.create(cdnEndpoint + response.getServices().get(AuthHeaders.STORAGE_URL).getPath());
}
// Placeholder for when the Object Storage service returns the CDN Management URL in the headers
return response.getServices().get(AuthHeaders.CDN_MANAGEMENT_URL);
}
}

View File

@ -0,0 +1,120 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.domain;
import java.net.URI;
import com.google.gson.annotations.SerializedName;
/**
*
* @author James Murty
*
*/
public class ContainerCDNMetadata implements Comparable<ContainerCDNMetadata> {
private String name;
private boolean cdn_enabled;
private long ttl;
@SerializedName("x-cdn-uri")
private URI cdn_uri;
private String referrer_acl;
private String useragent_acl;
private boolean log_retention;
public ContainerCDNMetadata(String name, boolean cdnEnabled, long ttl, URI cdnUri) {
this.name = name;
this.cdn_enabled = cdnEnabled;
this.ttl = ttl;
this.cdn_uri = cdnUri;
}
public ContainerCDNMetadata() {
}
/**
* Beware: The container name is not available from HEAD CDN responses and will be null. return
* the name of the container to which these CDN settings apply.
*/
public String getName() {
return name;
}
public URI getCDNUri() {
return cdn_uri;
}
public long getTTL() {
return ttl;
}
public boolean isCDNEnabled() {
return cdn_enabled;
}
public int compareTo(ContainerCDNMetadata o) {
if (getName() == null)
return -1;
return (this == o) ? 0 : getName().compareTo(o.getName());
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cdn_uri == null) ? 0 : cdn_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;
ContainerCDNMetadata other = (ContainerCDNMetadata) obj;
if (cdn_uri == null) {
if (other.cdn_uri != null)
return false;
} else if (!cdn_uri.equals(other.cdn_uri))
return false;
return true;
}
public String getReferrerACL() {
return referrer_acl;
}
public String getUseragentACL() {
return useragent_acl;
}
public boolean isLogRetention() {
return log_retention;
}
@Override
public String toString() {
return String.format(
"[name=%s, cdn_uri=%s, cdn_enabled=%s, log_retention=%s, referrer_acl=%s, ttl=%s, useragent_acl=%s]",
name, cdn_uri, cdn_enabled, log_retention, referrer_acl, ttl, useragent_acl);
}
}

View File

@ -0,0 +1,46 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import org.jclouds.hpcloud.object.storage.reference.HPCloudObjectStorageHeaders;
import org.jclouds.http.HttpResponse;
import org.jclouds.openstack.swift.domain.AccountMetadata;
import com.google.common.base.Function;
/**
* This parses {@link AccountMetadata} from HTTP headers.
*
* @author James Murty
*/
public class ParseCDNUriFromHeaders implements Function<HttpResponse, URI> {
/**
* parses the http response headers to provide the CDN URI string.
*/
public URI apply(final HttpResponse from) {
String cdnUri = checkNotNull(from.getFirstHeaderOrNull(HPCloudObjectStorageHeaders.CDN_URI),
HPCloudObjectStorageHeaders.CDN_URI);
return URI.create(cdnUri);
}
}

View File

@ -0,0 +1,75 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.newArrayList;
import java.util.List;
import java.net.URI;
import org.jclouds.hpcloud.object.storage.domain.ContainerCDNMetadata;
import org.jclouds.hpcloud.object.storage.reference.HPCloudObjectStorageHeaders;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.openstack.swift.domain.AccountMetadata;
import org.jclouds.rest.InvocationContext;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
/**
* This parses {@link AccountMetadata} from HTTP headers.
*
* @author James Murty
*/
public class ParseContainerCDNMetadataFromHeaders implements
Function<HttpResponse, ContainerCDNMetadata>, InvocationContext<ParseContainerCDNMetadataFromHeaders> {
private HttpRequest request;
/**
* parses the http response headers to create a new {@link ContainerCDNMetadata} object.
*/
public ContainerCDNMetadata apply(final HttpResponse from) {
String cdnUri = checkNotNull(from.getFirstHeaderOrNull(HPCloudObjectStorageHeaders.CDN_URI),
HPCloudObjectStorageHeaders.CDN_URI);
String cdnTTL = checkNotNull(from.getFirstHeaderOrNull(HPCloudObjectStorageHeaders.CDN_TTL),
HPCloudObjectStorageHeaders.CDN_TTL);
String cdnEnabled = checkNotNull(from.getFirstHeaderOrNull(HPCloudObjectStorageHeaders.CDN_ENABLED),
HPCloudObjectStorageHeaders.CDN_ENABLED);
if (cdnUri == null) {
// CDN is not enabled for this container.
return null;
} else {
// just need the name from the path
List<String> parts = newArrayList(Splitter.on('/').split(request.getEndpoint().getPath()));
return new ContainerCDNMetadata(parts.get(parts.size()-1), Boolean
.parseBoolean(cdnEnabled), Long.parseLong(cdnTTL), URI.create(cdnUri));
}
}
@Override
public ParseContainerCDNMetadataFromHeaders setContext(HttpRequest request) {
this.request = request;
return this;
}
}

View File

@ -0,0 +1,87 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.functions;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.Map.Entry;
import javax.inject.Inject;
import org.jclouds.date.DateService;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.openstack.swift.domain.ContainerMetadata;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
import org.jclouds.rest.InvocationContext;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
/**
* This parses @{link {@link org.jclouds.hpcloud.object.storage.domain.ContainerMetadata} from
* HTTP headers.
*
* @author Jeremy Daggett
*/
public class ParseContainerMetadataFromHeaders implements Function<HttpResponse, ContainerMetadata>,
InvocationContext<ParseContainerMetadataFromHeaders> {
private final DateService dateParser;
private GeneratedHttpRequest<?> request;
@Inject
public ParseContainerMetadataFromHeaders(DateService dateParser) {
this.dateParser = dateParser;
}
public ContainerMetadata apply(HttpResponse from) {
ContainerMetadata to = new ContainerMetadata();
to.setName(request.getArgs().get(0).toString());
to.setReadACL(from.getFirstHeaderOrNull(SwiftHeaders.CONTAINER_READ));
to.setBytes(new Long(from.getFirstHeaderOrNull(SwiftHeaders.CONTAINER_BYTES_USED)));
to.setCount(new Long(from.getFirstHeaderOrNull(SwiftHeaders.CONTAINER_OBJECT_COUNT)));
addUserMetadataTo(from, to);
return to;
}
@VisibleForTesting
void addUserMetadataTo(HttpResponse from, ContainerMetadata metadata) {
for (Entry<String, String> header : from.getHeaders().entries()) {
if (header.getKey() != null && header.getKey().startsWith(SwiftHeaders.CONTAINER_METADATA_PREFIX))
metadata.getMetadata().put((header.getKey().substring(SwiftHeaders.CONTAINER_METADATA_PREFIX.length())).toLowerCase(),
header.getValue());
}
}
@Override
public ParseContainerMetadataFromHeaders setContext(HttpRequest request) {
checkArgument(request instanceof GeneratedHttpRequest<?>, "note this handler requires a GeneratedHttpRequest");
this.request = (GeneratedHttpRequest<?>) request;
return this;
}
}

View File

@ -0,0 +1,81 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.options;
import java.util.Map;
import java.util.Map.Entry;
import org.jclouds.http.options.BaseHttpRequestOptions;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
/**
* Contains options supported in the REST API for the Create Container operation.
*
* This specifically enabes the Swift ACL for public reads using the 'X-Container-Read'
* header. This should be refactored into the Swift API.
*
* @author Jeremy Daggett
*/
public class CreateContainerOptions extends BaseHttpRequestOptions {
public static final CreateContainerOptions NONE = new CreateContainerOptions();
/**
* A name-value pair to associate with the container as metadata.
*/
public CreateContainerOptions withMetadata(Map<String, String> metadata) {
for (Entry<String, String> entry : metadata.entrySet()) {
if (entry.getKey().startsWith(SwiftHeaders.CONTAINER_METADATA_PREFIX)) {
this.headers.put(entry.getKey(), entry.getValue());
} else {
this.headers.put(SwiftHeaders.CONTAINER_METADATA_PREFIX + entry.getKey(),
entry.getValue());
}
}
return this;
}
/**
* Indicates whether a container may be accessed publicly
*/
public CreateContainerOptions withPublicAccess() {
this.headers.put(SwiftHeaders.CONTAINER_READ, ".r:*,.rlistings");
return this;
}
public static class Builder {
/**
* @see CreateContainerOptions#withPublicAccess
*/
public static CreateContainerOptions withPublicAccess() {
CreateContainerOptions options = new CreateContainerOptions();
return options.withPublicAccess();
}
/**
* @see CreateContainerOptions#withMetadata(Multimap<String, String>)
*/
public static CreateContainerOptions withMetadata(Map<String, String> metadata) {
CreateContainerOptions options = new CreateContainerOptions();
return (CreateContainerOptions) options.withMetadata(metadata);
}
}
}

View File

@ -0,0 +1,86 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.options;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import org.jclouds.http.options.BaseHttpRequestOptions;
/**
* Contains options supported in the REST API for the GET CDN containers operation.
*/
public class ListCDNContainerOptions extends BaseHttpRequestOptions {
public static final ListCDNContainerOptions NONE = new ListCDNContainerOptions();
public ListCDNContainerOptions enabledOnly() {
queryParameters.put("enabled_only", "true");
return this;
}
/**
* Indicates where to begin listing the identity's containers. The list will only include
* containers whose names occur lexicographically after the marker. This is convenient for
* pagination: To get the next page of results use the last container name of the current
* page as the marker.
*/
public ListCDNContainerOptions afterMarker(String marker) {
queryParameters.put("marker", checkNotNull(marker, "marker"));
return this;
}
/**
* The maximum number of containers that will be included in the response body.
* The server might return fewer than this many containers, but will not return more.
*/
public ListCDNContainerOptions maxResults(int limit) {
checkState(limit >= 0, "limit must be >= 0");
checkState(limit <= 10000, "limit must be <= 10000");
queryParameters.put("limit", Integer.toString(limit));
return this;
}
public static class Builder {
public static ListCDNContainerOptions enabledOnly() {
ListCDNContainerOptions options = new ListCDNContainerOptions();
return options.enabledOnly();
}
/**
* @see ListCDNContainerOptions#afterMarker(String)
*/
public static ListCDNContainerOptions afterMarker(String marker) {
ListCDNContainerOptions options = new ListCDNContainerOptions();
return options.afterMarker(marker);
}
/**
* @see ListCDNContainerOptions#limit(int)
*/
public static ListCDNContainerOptions maxResults(int limit) {
ListCDNContainerOptions options = new ListCDNContainerOptions();
return options.maxResults(limit);
}
}
}

View File

@ -0,0 +1,27 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* This package contains an HP Cloud Object Storage client implemented by {@link org.jclouds.http.HttpCommandExecutorService} commands.
*
* @see <a href="https://manage.hpcloud.com/pages/build/docs/object-storage/api" />
*
* @author Jeremy Daggett
*/
package org.jclouds.hpcloud.object.storage;

View File

@ -0,0 +1,34 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.reference;
/**
* Configuration properties and constants used by HP Cloud Object Storage.
*
* @author Jeremy Daggett
*/
public interface HPCloudObjectStorageConstants {
/**
* The CDN Endpoint property
*/
public static final String PROPERTY_CDN_ENDPOINT = "jclouds.hpcloud-object-storage.cdn.endpoint";
}

View File

@ -0,0 +1,40 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.reference;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
/**
* Additional headers specified by HP Cloud Object Storage REST API.
*
* @see <a href="https://manage.hpcloud.com/pages/build/docs/object-storage/api" />
* @author Jeremy Daggett
*
*/
public interface HPCloudObjectStorageHeaders extends SwiftHeaders {
public static final String CDN_ENABLED = "X-Cdn-Enabled";
public static final String CDN_LOG_RETENTION = "X-Log-Retention";
public static final String CDN_REFERRER_ACL = "X-Referrer-ACL";
public static final String CDN_TTL = "X-Ttl";
public static final String CDN_URI = "X-Cdn-Uri";
public static final String CDN_USER_AGENT_ACL = "X-User-Agent-ACL";
}

View File

@ -0,0 +1,25 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* This package contains properties and reference data used in HP Cloud Object Storage.
*
* @author Jeremy Daggett
*/
package org.jclouds.hpcloud.object.storage.reference;

View File

@ -0,0 +1 @@
org.jclouds.hpcloud.object.storage.HPCloudObjectStorageProviderMetadata

View File

@ -0,0 +1,159 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.net.URI;
import java.util.Set;
import org.jclouds.hpcloud.object.storage.domain.ContainerCDNMetadata;
import org.jclouds.hpcloud.object.storage.options.ListCDNContainerOptions;
import org.jclouds.openstack.swift.CommonSwiftClientLiveTest;
import org.jclouds.openstack.swift.domain.SwiftObject;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live")
public class HPCloudObjectStorageClientLiveTest extends CommonSwiftClientLiveTest<HPCloudObjectStorageClient> {
@Override
public HPCloudObjectStorageClient getApi() {
return (HPCloudObjectStorageClient) context.getProviderSpecificContext().getApi();
}
@Override
protected void testGetObjectContentType(SwiftObject getBlob) {
assertEquals(getBlob.getInfo().getContentType(), "application/x-www-form-urlencoded");
}
@Test
public void testListCDNContainers() {
// FIXFIX improve
/*
try {
Set<ContainerCDNMetadata> cdnMetadataList = getApi().listCDNContainers();
System.err.println(cdnMetadataList);
} catch (Exception e) {
e.printStackTrace();
}
*/
}
@Test
public void testCDNOperations() throws Exception {
final long minimumTTL = 60 * 60; // The minimum TTL is 1 hour
// Create two new containers for testing
final String containerNameWithCDN = getContainerName();
final String containerNameWithoutCDN = getContainerName();
try {
try {
getApi().disableCDN(containerNameWithCDN);
getApi().disableCDN(containerNameWithoutCDN);
} catch (Exception e) {
e.printStackTrace();
}
ContainerCDNMetadata cdnMetadata = null;
// Enable CDN with PUT for one container
final URI cdnUri = getApi().enableCDN(containerNameWithCDN);
assertTrue(cdnUri != null);
// Confirm CDN is enabled via HEAD request and has default TTL
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
assertTrue(cdnMetadata.isCDNEnabled());
assertEquals(cdnMetadata.getCDNUri(), cdnUri);
cdnMetadata = getApi().getCDNMetadata(containerNameWithoutCDN);
assert cdnMetadata == null || !cdnMetadata.isCDNEnabled() : containerNameWithoutCDN
+ " should not have metadata";
assert getApi().getCDNMetadata("DoesNotExist") == null;
// List CDN metadata for containers, and ensure all CDN info is
// available for enabled
// container
Set<ContainerCDNMetadata> cdnMetadataList = getApi().listCDNContainers();
assertTrue(cdnMetadataList.size() >= 1);
final long initialTTL = cdnMetadata.getTTL();
assertTrue(cdnMetadataList.contains(new ContainerCDNMetadata(containerNameWithCDN, true, initialTTL, cdnUri)));
/* Test listing with options FIXFIX
cdnMetadataList = getApi().listCDNContainers(ListCDNContainerOptions.Builder.enabledOnly());
assertTrue(Iterables.all(cdnMetadataList, new Predicate<ContainerCDNMetadata>() {
public boolean apply(ContainerCDNMetadata cdnMetadata) {
return cdnMetadata.isCDNEnabled();
}
}));
*/
cdnMetadataList = getApi().listCDNContainers(
ListCDNContainerOptions.Builder.afterMarker(
containerNameWithCDN.substring(0, containerNameWithCDN.length() - 1)).maxResults(1));
assertEquals(cdnMetadataList.size(), 1);
// Enable CDN with PUT for the same container, this time with a custom
// TTL
long ttl = 4000;
getApi().enableCDN(containerNameWithCDN, ttl);
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
assertTrue(cdnMetadata.isCDNEnabled());
assertEquals(cdnMetadata.getTTL(), ttl);
// Check POST by updating TTL settings
ttl = minimumTTL;
getApi().updateCDN(containerNameWithCDN, minimumTTL);
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
assertTrue(cdnMetadata.isCDNEnabled());
assertEquals(cdnMetadata.getTTL(), minimumTTL);
// Confirm that minimum allowed value for TTL is 3600, lower values are
// ignored.
getApi().updateCDN(containerNameWithCDN, 3599L);
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
assertEquals(cdnMetadata.getTTL(), 3599L);
// Disable CDN with POST
assertTrue(getApi().disableCDN(containerNameWithCDN));
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
assertEquals(cdnMetadata.isCDNEnabled(), false);
} catch (Exception e) {
e.printStackTrace();
} finally {
recycleContainer(containerNameWithCDN);
recycleContainer(containerNameWithoutCDN);
}
}
}

View File

@ -0,0 +1,37 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage;
import org.jclouds.providers.BaseProviderMetadataTest;
import org.jclouds.providers.ProviderMetadata;
import org.testng.annotations.Test;
/**
* The HPCloudObjectStorageProviderTest tests the {@link org.jclouds.hpcloud.object.storage.HPCloudObjectStorageProviderMetadata} class.
*
* @author Jeremy Daggett
*/
@Test(groups = "unit", testName = "HPCloudObjectStorageProviderTest")
public class HPCloudObjectStorageProviderTest extends BaseProviderMetadataTest {
public HPCloudObjectStorageProviderTest() {
super(new HPCloudObjectStorageProviderMetadata(), ProviderMetadata.BLOBSTORE_TYPE);
}
}

View File

@ -0,0 +1,38 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.integration;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.openstack.swift.blobstore.integration.SwiftBlobIntegrationLiveTest;
import org.testng.annotations.Test;
/**
* @author Jeremy Daggett
*/
@Test(groups = "live")
public class HPCloudObjectStorageBlobIntegrationLiveTest extends SwiftBlobIntegrationLiveTest {
@Override
protected void checkContentDisposition(Blob blob, String contentDisposition) {
assert blob.getPayload().getContentMetadata().getContentDisposition().startsWith(contentDisposition) : blob
.getPayload().getContentMetadata().getContentDisposition();
assert blob.getMetadata().getContentMetadata().getContentDisposition().startsWith(contentDisposition) : blob
.getMetadata().getContentMetadata().getContentDisposition();
}
}

View File

@ -0,0 +1,30 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.integration;
import org.jclouds.openstack.swift.blobstore.integration.SwiftBlobLiveTest;
import org.testng.annotations.Test;
/**
* @author Jeremy Daggett
*/
@Test(groups = { "live" })
public class HPCloudObjectStorageBlobLiveTest extends SwiftBlobLiveTest {
}

View File

@ -0,0 +1,30 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.integration;
import org.jclouds.openstack.swift.blobstore.integration.SwiftBlobMapIntegrationLiveTest;
import org.testng.annotations.Test;
/**
* @author Jeremy Daggett
*/
@Test(groups = "live")
public class HPCloudObjectStorageBlobMapIntegrationLiveTest extends SwiftBlobMapIntegrationLiveTest {
}

View File

@ -0,0 +1,30 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.integration;
import org.jclouds.openstack.swift.blobstore.integration.SwiftBlobSignerLiveTest;
import org.testng.annotations.Test;
/**
* @author Jeremy Daggett
*/
@Test(groups = { "live" })
public class HPCloudObjectStorageBlobSignerLiveTest extends SwiftBlobSignerLiveTest {
}

View File

@ -0,0 +1,30 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.integration;
import org.jclouds.openstack.swift.blobstore.integration.SwiftContainerIntegrationLiveTest;
import org.testng.annotations.Test;
/**
* @author Jeremy Daggett
*/
@Test(groups = "live")
public class HPCloudObjectStorageContainerIntegrationLiveTest extends SwiftContainerIntegrationLiveTest {
}

View File

@ -0,0 +1,30 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.integration;
import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest;
import org.testng.annotations.Test;
/**
* @author Jeremy Daggett
*/
@Test(groups = { "live" })
public class HPCloudObjectStorageContainerLiveTest extends BaseContainerLiveTest {
}

View File

@ -0,0 +1,30 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.integration;
import org.jclouds.openstack.swift.blobstore.integration.SwiftInputStreamMapIntegrationLiveTest;
import org.testng.annotations.Test;
/**
* @author Jeremy Daggett
*/
@Test(groups = "live")
public class HPCloudObjectStorageInputStreamMapIntegrationLiveTest extends SwiftInputStreamMapIntegrationLiveTest {
}

View File

@ -0,0 +1,30 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.integration;
import org.jclouds.openstack.swift.blobstore.integration.SwiftServiceIntegrationLiveTest;
import org.testng.annotations.Test;
/**
* @author Jeremy Daggett
*/
@Test(groups = "live")
public class HPCloudObjectStorageServiceIntegrationLiveTest extends SwiftServiceIntegrationLiveTest {
}

View File

@ -0,0 +1,32 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.blobstore.integration;
import org.jclouds.openstack.swift.blobstore.integration.SwiftTestInitializer;
/**
* @author Jeremy Daggett
*/
public class HPCloudObjectStorageTestInitializer extends SwiftTestInitializer {
public HPCloudObjectStorageTestInitializer() {
provider = "hpcloud-object-storage";
}
}

View File

@ -0,0 +1,69 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.functions;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.URI;
import java.util.Set;
import java.util.SortedSet;
import org.jclouds.hpcloud.object.storage.domain.ContainerCDNMetadata;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSortedSet;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ParseContainerCDNMetadataListFromJsonResponse}
*
* @author Jeremy Daggett
*/
@Test(groups = "unit")
public class ParseContainerCDNMetadataListFromJsonResponseTest {
Injector i = Guice.createInjector(new GsonModule());
@Test
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/test_list_cdn.json");
Set<ContainerCDNMetadata> expects = ImmutableSortedSet.of(
new ContainerCDNMetadata("hpcloud-blobstore.testCDNOperationsContainerWithCDN", false, 3600,
URI.create("https://cdnmgmt.hpcloud.net:8080/v1/AUTH_test/")),
new ContainerCDNMetadata("hpcloud-blobstore5", true, 28800,
URI.create("https://cdnmgmt.hpcloud.net:8080/v1/AUTH_test/")),
new ContainerCDNMetadata("hpcloud-cfcdnint.testCDNOperationsContainerWithCDN", false, 3600,
URI.create("https://cdnmgmt.hpcloud.net:8080/v1/AUTH_test/")));
ParseJson<SortedSet<ContainerCDNMetadata>> parser = i.getInstance(Key
.get(new TypeLiteral<ParseJson<SortedSet<ContainerCDNMetadata>>>() {
}));
assertEquals(parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is))), expects);
}
}

View File

@ -0,0 +1,70 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.object.storage.options;
import static org.testng.Assert.assertEquals;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
* Tests behavior of {@code CreateContainerOptions}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class CreateContainerOptionsTest {
public void testPublicAccess() {
CreateContainerOptions options = new CreateContainerOptions().withPublicAccess();
assertEquals(ImmutableList.of(".r:*,.rlistings"),
options.buildRequestHeaders().get("X-Container-Read"));
}
public void testPublicAccessStatic() {
CreateContainerOptions options = CreateContainerOptions.Builder.withPublicAccess();
assertEquals(ImmutableList.of(".r:*,.rlistings"),
options.buildRequestHeaders().get("X-Container-Read"));
}
public void testMetadata() {
CreateContainerOptions options = new CreateContainerOptions().withMetadata(ImmutableMap
.of("test", "foo"));
assertEquals(ImmutableList.of("foo"), options.buildRequestHeaders().get(
SwiftHeaders.CONTAINER_METADATA_PREFIX + "test"));
}
public void testMetadataAlreadyPrefixed() {
CreateContainerOptions options = new CreateContainerOptions().withMetadata(ImmutableMap
.of(SwiftHeaders.CONTAINER_METADATA_PREFIX + "test", "foo"));
assertEquals(ImmutableList.of("foo"), options.buildRequestHeaders().get(
SwiftHeaders.CONTAINER_METADATA_PREFIX + "test"));
}
public void testMetadataStatic() {
CreateContainerOptions options = CreateContainerOptions.Builder
.withMetadata(ImmutableMap.of("test", "foo"));
assertEquals(ImmutableList.of("foo"), options.buildRequestHeaders().get(
SwiftHeaders.CONTAINER_METADATA_PREFIX + "test"));
}
}

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!--
For more configuration infromation and examples see the Apache
Log4j website: http://logging.apache.org/log4j/
-->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false">
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-wire.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="BLOBSTOREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-blobstore.log" />
<param name="Append" value="true" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
</layout>
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<appender name="ASYNCBLOBSTORE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="BLOBSTOREFILE" />
</appender>
<!-- ================ -->
<!-- Limit categories -->
<!-- ================ -->
<category name="org.jclouds">
<priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
<category name="jclouds.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<!--
NOTE!! enabling this logger will cause the following test to
fail BaseBlobIntegrationTest.testPutObjectStream <category
name="jclouds.wire"> <priority value="DEBUG" /> <appender-ref
ref="ASYNCWIRE" /> </category>
-->
<category name="jclouds.blobstore">
<priority value="DEBUG" />
<appender-ref ref="ASYNCBLOBSTORE" />
</category>
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<root>
<priority value="WARN" />
</root>
</log4j:configuration>

View File

@ -0,0 +1,5 @@
[
{"name":"hpcloud-blobstore.testCDNOperationsContainerWithCDN","cdn_enabled":"false","ttl":3600,"cdn_uri":"https://cdnmgmt.hpcloud.net:8080/v1/AUTH_test/","referrer_acl":"","useragent_acl":"", "log_retention":"false"},
{"name":"hpcloud-blobstore5","cdn_enabled":"true","ttl":28800,"cdn_uri":"https://cdnmgmt.hpcloud.net:8080/v1/AUTH_test/","referrer_acl":"","useragent_acl":"", "log_retention":"false"},
{"name":"hpcloud-cfcdnint.testCDNOperationsContainerWithCDN","cdn_enabled":"false","ttl":3600,"cdn_uri":"https://cdnmgmt.hpcloud.net:8080/v1/AUTH_test/","referrer_acl":"","useragent_acl":"", "log_retention":"false"}
]

View File

@ -67,5 +67,6 @@
<module>go2cloud-jhb1</module> <module>go2cloud-jhb1</module>
<module>softlayer</module> <module>softlayer</module>
<module>ninefold-compute</module> <module>ninefold-compute</module>
<module>hpcloud-object-storage</module>
</modules> </modules>
</project> </project>