mirror of https://github.com/apache/jclouds.git
Issue 879:keystone v2 hpcloud-objectstorage provider
This commit is contained in:
commit
71f4e5c0d9
|
@ -243,5 +243,8 @@ filesystem.propertiesbuilder=org.jclouds.filesystem.FilesystemBlobStorePropertie
|
||||||
hpcloud-objectstorage-lvs.contextbuilder=org.jclouds.hpcloud.objectstorage.lvs.HPCloudObjectStorageLasVegasContextBuilder
|
hpcloud-objectstorage-lvs.contextbuilder=org.jclouds.hpcloud.objectstorage.lvs.HPCloudObjectStorageLasVegasContextBuilder
|
||||||
hpcloud-objectstorage-lvs.propertiesbuilder=org.jclouds.hpcloud.objectstorage.lvs.HPCloudObjectStorageLasVegasPropertiesBuilder
|
hpcloud-objectstorage-lvs.propertiesbuilder=org.jclouds.hpcloud.objectstorage.lvs.HPCloudObjectStorageLasVegasPropertiesBuilder
|
||||||
|
|
||||||
|
hpcloud-objectstorage.contextbuilder=org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageContextBuilder
|
||||||
|
hpcloud-objectstorage.propertiesbuilder=org.jclouds.hpcloud.objectstorage.HPCloudObjectStoragePropertiesBuilder
|
||||||
|
|
||||||
hpcloud-compute.contextbuilder=org.jclouds.hpcloud.compute.HPCloudComputeContextBuilder
|
hpcloud-compute.contextbuilder=org.jclouds.hpcloud.compute.HPCloudComputeContextBuilder
|
||||||
hpcloud-compute.propertiesbuilder=org.jclouds.hpcloud.compute.HPCloudComputePropertiesBuilder
|
hpcloud-compute.propertiesbuilder=org.jclouds.hpcloud.compute.HPCloudComputePropertiesBuilder
|
||||||
|
|
|
@ -103,7 +103,7 @@ public class HPCloudComputeProviderMetadata extends BaseProviderMetadata {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getLinkedServices() {
|
public Set<String> getLinkedServices() {
|
||||||
return ImmutableSet.of("hpcloud-compute", "hpcloud-objectstorage-lvs");
|
return ImmutableSet.of("hpcloud-compute", "hpcloud-objectstorage");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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.
|
|
@ -0,0 +1,169 @@
|
||||||
|
<?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.5.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../../project/pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<groupId>org.jclouds.labs</groupId>
|
||||||
|
<artifactId>hpcloud-objectstorage</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.objectstorage.blobstore.integration.HPCloudObjectStorageTestInitializer</test.initializer>
|
||||||
|
<test.hpcloud-objectstorage.endpoint>https://region-a.geo-1.identity.hpcloudsvc.com:35357</test.hpcloud-objectstorage.endpoint>
|
||||||
|
<test.hpcloud-objectstorage.api-version>1.0</test.hpcloud-objectstorage.api-version>
|
||||||
|
<test.hpcloud-objectstorage.build-version></test.hpcloud-objectstorage.build-version>
|
||||||
|
<test.hpcloud-objectstorage.identity>FIXME_IDENTITY</test.hpcloud-objectstorage.identity>
|
||||||
|
<test.hpcloud-objectstorage.credential>FIXME_CREDENTIAL</test.hpcloud-objectstorage.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-objectstorage.endpoint</name>
|
||||||
|
<value>${test.hpcloud-objectstorage.endpoint}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>test.hpcloud-objectstorage.api-version</name>
|
||||||
|
<value>${test.hpcloud-objectstorage.api-version}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>test.hpcloud-objectstorage.build-version</name>
|
||||||
|
<value>${test.hpcloud-objectstorage.build-version}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>test.hpcloud-objectstorage.identity</name>
|
||||||
|
<value>${test.hpcloud-objectstorage.identity}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>test.hpcloud-objectstorage.credential</name>
|
||||||
|
<value>${test.hpcloud-objectstorage.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.objectstorage*;version="${project.version}"</Export-Package>
|
||||||
|
<Import-Package>org.jclouds*;version="${project.version}",*</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
|
@ -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.objectstorage;
|
||||||
|
|
||||||
|
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 {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
/**
|
||||||
|
* 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.objectstorage;
|
||||||
|
|
||||||
|
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.objectstorage.domain.ContainerCDNMetadata;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.functions.ParseCDNUriFromHeaders;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.functions.ParseContainerCDNMetadataFromHeaders;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.functions.ParseContainerMetadataFromHeaders;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.options.CreateContainerOptions;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.options.ListCDNContainerOptions;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.reference.HPCloudObjectStorageHeaders;
|
||||||
|
import org.jclouds.hpcloud.services.HPExtensionCDN;
|
||||||
|
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||||
|
import org.jclouds.openstack.services.ObjectStore;
|
||||||
|
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.annotations.Beta;
|
||||||
|
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 java.util.concurrent.ExecutionException} as documented in
|
||||||
|
* {@link ListenableFuture#get()}.
|
||||||
|
*
|
||||||
|
* @see HPCloudObjectStorageClient
|
||||||
|
* @see <a href="https://manage.hpcloud.com/pages/build/docs/objectstorage-lvs/api">HP Cloud Object Storage API</a>
|
||||||
|
* @author Jeremy Daggett
|
||||||
|
*/
|
||||||
|
@SkipEncoding('/')
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@Endpoint(ObjectStore.class)
|
||||||
|
public interface HPCloudObjectStorageAsyncClient extends CommonSwiftAsyncClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see HPCloudObjectStorageClient#getCDNMetadata(String)
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
@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#listCDNContainers(ListCDNContainerOptions)
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
@GET
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@QueryParams(keys = "format", values = "json")
|
||||||
|
@Path("/")
|
||||||
|
@Endpoint(HPExtensionCDN.class)
|
||||||
|
ListenableFuture<? extends Set<ContainerCDNMetadata>> listCDNContainers(ListCDNContainerOptions... options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see HPCloudObjectStorageClient#getCDNMetadata(String)
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
@HEAD
|
||||||
|
@ResponseParser(ParseContainerCDNMetadataFromHeaders.class)
|
||||||
|
@ExceptionParser(ReturnNullOnContainerNotFound.class)
|
||||||
|
@Path("/{container}")
|
||||||
|
@Endpoint(HPExtensionCDN.class)
|
||||||
|
ListenableFuture<ContainerCDNMetadata> getCDNMetadata(@PathParam("container") String container);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see HPCloudObjectStorageClient#enableCDN(String, long)
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
@PUT
|
||||||
|
@Path("/{container}")
|
||||||
|
@Headers(keys = HPCloudObjectStorageHeaders.CDN_ENABLED, values = "True")
|
||||||
|
@ResponseParser(ParseCDNUriFromHeaders.class)
|
||||||
|
@Endpoint(HPExtensionCDN.class)
|
||||||
|
ListenableFuture<URI> enableCDN(@PathParam("container") String container,
|
||||||
|
@HeaderParam(HPCloudObjectStorageHeaders.CDN_TTL) long ttl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see HPCloudObjectStorageClient#enableCDN(String)
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
@PUT
|
||||||
|
@Path("/{container}")
|
||||||
|
@Headers(keys = HPCloudObjectStorageHeaders.CDN_ENABLED, values = "True")
|
||||||
|
@ResponseParser(ParseCDNUriFromHeaders.class)
|
||||||
|
@Endpoint(HPExtensionCDN.class)
|
||||||
|
ListenableFuture<URI> enableCDN(@PathParam("container") String container);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see HPCloudObjectStorageClient#updateCDN(String, long)
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
@POST
|
||||||
|
@Path("/{container}")
|
||||||
|
@ResponseParser(ParseCDNUriFromHeaders.class)
|
||||||
|
@Endpoint(HPExtensionCDN.class)
|
||||||
|
ListenableFuture<URI> updateCDN(@PathParam("container") String container,
|
||||||
|
@HeaderParam(HPCloudObjectStorageHeaders.CDN_TTL) long ttl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see HPCloudObjectStorageClient#disableCDN(String)
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
@PUT
|
||||||
|
@Path("/{container}")
|
||||||
|
@Headers(keys = HPCloudObjectStorageHeaders.CDN_ENABLED, values = "False")
|
||||||
|
@Endpoint(HPExtensionCDN.class)
|
||||||
|
ListenableFuture<Boolean> disableCDN(@PathParam("container") String container);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/**
|
||||||
|
* 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.objectstorage;
|
||||||
|
|
||||||
|
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.objectstorage.domain.ContainerCDNMetadata;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.options.CreateContainerOptions;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.options.ListCDNContainerOptions;
|
||||||
|
import org.jclouds.openstack.swift.CommonSwiftClient;
|
||||||
|
import org.jclouds.openstack.swift.domain.ContainerMetadata;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
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 java.util.concurrent.ExecutionException} as documented in {@link ListenableFuture#get()}.
|
||||||
|
*
|
||||||
|
* @see org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageClient
|
||||||
|
* @see <a href="https://manage.hpcloud.com/pages/build/docs/objectstorage-lvs/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);
|
||||||
|
|
||||||
|
ContainerMetadata getContainerMetadata(String container);
|
||||||
|
|
||||||
|
@Beta
|
||||||
|
Set<ContainerCDNMetadata> listCDNContainers(ListCDNContainerOptions... options);
|
||||||
|
|
||||||
|
@Beta
|
||||||
|
ContainerCDNMetadata getCDNMetadata(String container);
|
||||||
|
|
||||||
|
@Beta
|
||||||
|
URI enableCDN(String container, long ttl);
|
||||||
|
|
||||||
|
@Beta
|
||||||
|
URI enableCDN(String container);
|
||||||
|
|
||||||
|
@Beta
|
||||||
|
URI updateCDN(String container, long ttl);
|
||||||
|
|
||||||
|
@Beta
|
||||||
|
boolean disableCDN(String container);
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.blobstore.config.HPCloudObjectStorageBlobStoreContextModule;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.objectstorage;
|
||||||
|
|
||||||
|
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_ISO3166_CODES;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
||||||
|
import org.jclouds.openstack.services.ServiceType;
|
||||||
|
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(KeystoneProperties.SERVICE_TYPE, ServiceType.OBJECT_STORE);
|
||||||
|
// TODO: this doesn't actually do anything yet.
|
||||||
|
properties.setProperty(KeystoneProperties.VERSION, "2.0");
|
||||||
|
properties.setProperty(PROPERTY_ISO3166_CODES, "US-NV");
|
||||||
|
properties.setProperty(PROPERTY_ENDPOINT, "https://region-a.geo-1.identity.hpcloudsvc.com:35357");
|
||||||
|
properties.setProperty(PROPERTY_API_VERSION, "1.0");
|
||||||
|
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage;
|
||||||
|
|
||||||
|
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-objectstorage";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@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 "email:tenantId";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getCredentialName() {
|
||||||
|
return "API 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("TODO");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Set<String> getLinkedServices() {
|
||||||
|
return ImmutableSet.of("hpcloud-compute", "hpcloud-objectstorage");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Set<String> getIso3166Codes() {
|
||||||
|
return ImmutableSet.of("US-NV");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.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.objectstorage.HPCloudObjectStorageAsyncClient;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageClient;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
* 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.objectstorage.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.objectstorage.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/**
|
||||||
|
* 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.objectstorage.blobstore.config;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageClient;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.blobstore.HPCloudObjectStorageAsyncBlobStore;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.blobstore.HPCloudObjectStorageBlobStore;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.blobstore.functions.HPCloudObjectStorageObjectToBlobMetadata;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.domain.ContainerCDNMetadata;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
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.annotations.Beta;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class HPCloudObjectStorageBlobStoreContextModule extends SwiftBlobStoreContextModule {
|
||||||
|
|
||||||
|
@Beta
|
||||||
|
@Singleton
|
||||||
|
public static final class GetCDNMetadata extends CacheLoader<String, URI> {
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
private final HPCloudObjectStorageClient client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public GetCDNMetadata(HPCloudObjectStorageClient client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URI load(String container) {
|
||||||
|
try {
|
||||||
|
ContainerCDNMetadata md = client.getCDNMetadata(container);
|
||||||
|
return md != null ? md.getCDNUri() : null;
|
||||||
|
} catch (HttpResponseException e) {
|
||||||
|
// TODO: this is due to beta status
|
||||||
|
logger.trace("couldn't get cdn metadata for %s: %s", container, e.getMessage());
|
||||||
|
return null;
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
logger.trace("CDN may not be enabled. Couldn't get cdn metadata for %s: %s", container, e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "getCDNMetadata()";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected LoadingCache<String, URI> cdnContainer(GetCDNMetadata loader) {
|
||||||
|
return CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.SECONDS).build(loader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
super.configure();
|
||||||
|
bind(SwiftBlobStore.class).to(HPCloudObjectStorageBlobStore.class);
|
||||||
|
bind(SwiftAsyncBlobStore.class).to(HPCloudObjectStorageAsyncBlobStore.class);
|
||||||
|
bind(ObjectToBlobMetadata.class).to(HPCloudObjectStorageObjectToBlobMetadata.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.objectstorage.blobstore.functions;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageClient;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class EnableCDNAndCache implements Function<String, URI> {
|
||||||
|
private final LoadingCache<String, URI> cdnContainer;
|
||||||
|
private final HPCloudObjectStorageClient sync;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public EnableCDNAndCache(HPCloudObjectStorageClient sync, LoadingCache<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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* 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.objectstorage.blobstore.functions;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class PublicUriForObjectInfo implements Function<ObjectInfo, URI> {
|
||||||
|
private final LoadingCache<String, URI> cdnContainer;
|
||||||
|
private final Provider<UriBuilder> uriBuilders;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public PublicUriForObjectInfo(LoadingCache<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.getUnchecked(from.getContainer())).path(from.getName()).replaceQuery("")
|
||||||
|
.build();
|
||||||
|
} catch (CacheLoader.InvalidCacheLoadException e) {
|
||||||
|
// nulls not permitted from cache loader
|
||||||
|
return null;
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// nulls not permitted from cache loader
|
||||||
|
// TODO this shouldn't occur when the above exception is reliably presented
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
/**
|
||||||
|
* 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.objectstorage.config;
|
||||||
|
|
||||||
|
import static org.jclouds.util.Suppliers2.getLastValueInMap;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import com.google.inject.Scopes;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageAsyncClient;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageClient;
|
||||||
|
import org.jclouds.hpcloud.services.HPExtensionCDN;
|
||||||
|
import org.jclouds.hpcloud.services.HPExtensionServiceType;
|
||||||
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
|
import org.jclouds.http.RequiresHttp;
|
||||||
|
import org.jclouds.http.annotation.ClientError;
|
||||||
|
import org.jclouds.http.annotation.Redirection;
|
||||||
|
import org.jclouds.http.annotation.ServerError;
|
||||||
|
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||||
|
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||||
|
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
||||||
|
import org.jclouds.location.suppliers.RegionIdToURISupplier;
|
||||||
|
import org.jclouds.location.suppliers.implicit.GetRegionIdMatchingProviderURIOrNull;
|
||||||
|
import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstRegionOptionallyMatchingRegionId;
|
||||||
|
import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
|
||||||
|
import org.jclouds.openstack.services.ServiceType;
|
||||||
|
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||||
|
import org.jclouds.openstack.swift.CommonSwiftClient;
|
||||||
|
import org.jclouds.openstack.swift.Storage;
|
||||||
|
import org.jclouds.openstack.swift.config.SwiftObjectModule;
|
||||||
|
import org.jclouds.openstack.swift.handlers.ParseSwiftErrorFromHttpResponse;
|
||||||
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
|
import org.jclouds.rest.annotations.ApiVersion;
|
||||||
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@ConfiguresRestClient
|
||||||
|
@RequiresHttp
|
||||||
|
public class HPCloudObjectStorageRestClientModule extends
|
||||||
|
RestClientModule<HPCloudObjectStorageClient, HPCloudObjectStorageAsyncClient> {
|
||||||
|
|
||||||
|
public HPCloudObjectStorageRestClientModule() {
|
||||||
|
super(HPCloudObjectStorageClient.class, HPCloudObjectStorageAsyncClient.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void configure() {
|
||||||
|
install(new SwiftObjectModule());
|
||||||
|
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||||
|
super.configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void installLocations() {
|
||||||
|
super.installLocations();
|
||||||
|
// TODO: select this from KeystoneProperties.VERSION;
|
||||||
|
install(KeystoneAuthenticationModule.forRegions());
|
||||||
|
bind(ImplicitLocationSupplier.class).to(OnlyLocationOrFirstZone.class).in(Scopes.SINGLETON);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void bindErrorHandlers() {
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseSwiftErrorFromHttpResponse.class);
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseSwiftErrorFromHttpResponse.class);
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseSwiftErrorFromHttpResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
CommonSwiftClient provideCommonSwiftClient(HPCloudObjectStorageClient in) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
CommonSwiftAsyncClient provideCommonSwiftClient(HPCloudObjectStorageAsyncClient in) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@HPExtensionCDN
|
||||||
|
protected Supplier<URI> provideCDNUrl(RegionIdToURISupplier.Factory factory, @ApiVersion String apiVersion) {
|
||||||
|
return getLastValueInMap(factory.createForApiTypeAndVersion(HPExtensionServiceType.CDN, apiVersion));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Storage
|
||||||
|
protected Supplier<URI> provideStorageUrl(RegionIdToURISupplier.Factory factory, @ApiVersion String apiVersion) {
|
||||||
|
return getLastValueInMap(factory.createForApiTypeAndVersion(ServiceType.OBJECT_STORE, apiVersion));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.objectstorage.functions;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.hpcloud.objectstorage.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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/**
|
||||||
|
* 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.objectstorage.functions;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.collect.Lists.newArrayList;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jclouds.hpcloud.objectstorage.domain.ContainerCDNMetadata;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* 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.objectstorage.functions;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
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.objectstorage.domain.ContainerMetadata} from
|
||||||
|
* HTTP headers.
|
||||||
|
*
|
||||||
|
* @author Jeremy Daggett
|
||||||
|
*/
|
||||||
|
public class ParseContainerMetadataFromHeaders implements Function<HttpResponse, ContainerMetadata>,
|
||||||
|
InvocationContext<ParseContainerMetadataFromHeaders> {
|
||||||
|
private GeneratedHttpRequest<?> request;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.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 org.jclouds.hpcloud.objectstorage.options.CreateContainerOptions#withPublicAccess
|
||||||
|
*/
|
||||||
|
public static CreateContainerOptions withPublicAccess() {
|
||||||
|
CreateContainerOptions options = new CreateContainerOptions();
|
||||||
|
return options.withPublicAccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jclouds.hpcloud.objectstorage.options.CreateContainerOptions#withMetadata(Multimap<String, String>)
|
||||||
|
*/
|
||||||
|
public static CreateContainerOptions withMetadata(Map<String, String> metadata) {
|
||||||
|
CreateContainerOptions options = new CreateContainerOptions();
|
||||||
|
return (CreateContainerOptions) options.withMetadata(metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.objectstorage.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 org.jclouds.hpcloud.objectstorage.options.ListCDNContainerOptions#afterMarker(String)
|
||||||
|
*/
|
||||||
|
public static ListCDNContainerOptions afterMarker(String marker) {
|
||||||
|
ListCDNContainerOptions options = new ListCDNContainerOptions();
|
||||||
|
return options.afterMarker(marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.jclouds.hpcloud.objectstorage.options.ListCDNContainerOptions#limit(int)
|
||||||
|
*/
|
||||||
|
public static ListCDNContainerOptions maxResults(int limit) {
|
||||||
|
ListCDNContainerOptions options = new ListCDNContainerOptions();
|
||||||
|
return options.maxResults(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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/objectstorage-lvs/api" />
|
||||||
|
*
|
||||||
|
* @author Jeremy Daggett
|
||||||
|
*/
|
||||||
|
package org.jclouds.hpcloud.objectstorage;
|
|
@ -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.objectstorage.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-objectstorage-lvs.cdn.endpoint";
|
||||||
|
}
|
|
@ -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.objectstorage.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/objectstorage-lvs/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";
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.reference;
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* 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.services;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HP Extension Block Store Service
|
||||||
|
*
|
||||||
|
* @author Jeremy Daggett
|
||||||
|
* @see <a href="http://docs.openstack.org/api/openstack-typeentity-service/2.0/content/Identity-Service-Concepts-e1362.html"
|
||||||
|
* />
|
||||||
|
* @see HPExtensionServiceType#BLOCK_STORE
|
||||||
|
*/
|
||||||
|
@Retention(value = RetentionPolicy.RUNTIME)
|
||||||
|
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||||
|
@Qualifier
|
||||||
|
public @interface HPExtensionBlockStore {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* 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.services;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CDN
|
||||||
|
*
|
||||||
|
* @author Jeremy Daggett
|
||||||
|
* @see <a href="http://docs.openstack.org/api/openstack-typeentity-service/2.0/content/Identity-Service-Concepts-e1362.html"
|
||||||
|
* />
|
||||||
|
* @see HPExtensionServiceType#CDN
|
||||||
|
*/
|
||||||
|
@Retention(value = RetentionPolicy.RUNTIME)
|
||||||
|
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||||
|
@Qualifier
|
||||||
|
public @interface HPExtensionCDN {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* 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, Name 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.services;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.services.ServiceType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An HP Extension Service, such as CDN, or Block Store Service.
|
||||||
|
* A service provides one or more endpoints through which users can access resources and perform
|
||||||
|
* (presumably useful) operations.
|
||||||
|
*
|
||||||
|
* @author Jeremy Daggett
|
||||||
|
* @see <a href="http://docs.openstack.org/api/openstack-typeentity-service/2.0/content/Identity-Service-Concepts-e1362.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
public interface HPExtensionServiceType extends ServiceType {
|
||||||
|
/**
|
||||||
|
* CDN
|
||||||
|
*/
|
||||||
|
public static final String CDN = "hpext:cdn";
|
||||||
|
/**
|
||||||
|
* Block Storage
|
||||||
|
*/
|
||||||
|
public static final String BLOCK_STORE = "hpext:block-store";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageProviderMetadata
|
|
@ -0,0 +1,145 @@
|
||||||
|
/**
|
||||||
|
* 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.objectstorage;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.hpcloud.objectstorage.domain.ContainerCDNMetadata;
|
||||||
|
import org.jclouds.hpcloud.objectstorage.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", testName = "HPCloudObjectStorageClientLiveTest")
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDN service due to go live Q1 2012
|
||||||
|
@Test(enabled = true)
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage;
|
||||||
|
|
||||||
|
import org.jclouds.providers.BaseProviderMetadataTest;
|
||||||
|
import org.jclouds.providers.ProviderMetadata;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The HPCloudObjectStorageProviderTest tests the {@link org.jclouds.hpcloud.objectstorage.HPCloudObjectStorageProviderMetadata} class.
|
||||||
|
*
|
||||||
|
* @author Jeremy Daggett
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "HPCloudObjectStorageProviderTest")
|
||||||
|
public class HPCloudObjectStorageProviderTest extends BaseProviderMetadataTest {
|
||||||
|
|
||||||
|
public HPCloudObjectStorageProviderTest() {
|
||||||
|
super(new HPCloudObjectStorageProviderMetadata(), ProviderMetadata.BLOBSTORE_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.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 {
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.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 {
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.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 {
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.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 {
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.blobstore.integration;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jeremy Daggett
|
||||||
|
*/
|
||||||
|
@Test(groups = { "live" })
|
||||||
|
public class HPCloudObjectStorageContainerLiveTest extends BaseContainerLiveTest {
|
||||||
|
|
||||||
|
@Test(enabled = false)
|
||||||
|
//@Test(expectedExceptions=UnsupportedOperationException.class)
|
||||||
|
public void testPublicAccess() throws MalformedURLException, InterruptedException, IOException {
|
||||||
|
super.testPublicAccess();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.objectstorage.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 {
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.blobstore.integration;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.swift.blobstore.integration.SwiftServiceIntegrationLiveTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jeremy Daggett
|
||||||
|
*/
|
||||||
|
@Test(groups = "live")
|
||||||
|
public class HPCloudObjectStorageServiceIntegrationLiveTest extends SwiftServiceIntegrationLiveTest {
|
||||||
|
@Override
|
||||||
|
protected Set<String> getIso3166Codes() {
|
||||||
|
return ImmutableSet.<String> of("US-NV");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.blobstore.integration;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.swift.blobstore.integration.SwiftTestInitializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jeremy Daggett
|
||||||
|
*/
|
||||||
|
public class HPCloudObjectStorageTestInitializer extends SwiftTestInitializer {
|
||||||
|
|
||||||
|
public HPCloudObjectStorageTestInitializer() {
|
||||||
|
provider = "hpcloud-objectstorage-lvs";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.objectstorage.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.objectstorage.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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package org.jclouds.hpcloud.objectstorage.internal;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
import org.jclouds.blobstore.BlobStore;
|
||||||
|
import org.jclouds.blobstore.BlobStoreContext;
|
||||||
|
import org.jclouds.blobstore.BlobStoreContextFactory;
|
||||||
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.logging.config.NullLoggingModule;
|
||||||
|
import org.jclouds.rest.BaseRestClientExpectTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
|
@Test(groups = "unit", testName = "HPCloudObjectStorageExpectTest")
|
||||||
|
public class HPCloudObjectStorageExpectTest extends BaseRestClientExpectTest<BlobStore> {
|
||||||
|
|
||||||
|
|
||||||
|
protected HttpRequest keystoneAuthWithUsernameAndPassword;
|
||||||
|
protected HttpRequest keystoneAuthWithAccessKeyAndSecretKey;
|
||||||
|
protected String authToken;
|
||||||
|
protected HttpResponse responseWithKeystoneAccess;
|
||||||
|
|
||||||
|
public HPCloudObjectStorageExpectTest() {
|
||||||
|
provider = "hpcloud-objectstorage";
|
||||||
|
keystoneAuthWithUsernameAndPassword = KeystoneFixture.INSTANCE.initialAuthWithUsernameAndPassword(identity,
|
||||||
|
credential);
|
||||||
|
keystoneAuthWithAccessKeyAndSecretKey = KeystoneFixture.INSTANCE.initialAuthWithAccessKeyAndSecretKey(identity,
|
||||||
|
credential);
|
||||||
|
authToken = KeystoneFixture.INSTANCE.getAuthToken();
|
||||||
|
responseWithKeystoneAccess = KeystoneFixture.INSTANCE.responseWithAccess();
|
||||||
|
|
||||||
|
identity = KeystoneFixture.INSTANCE.getTenantName() + ":" + identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlobStore createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
|
||||||
|
return new BlobStoreContextFactory(setupRestProperties())
|
||||||
|
.createContext(provider, identity, credential, ImmutableSet.<Module>of(new ExpectModule(fn),
|
||||||
|
new NullLoggingModule(), module), props)
|
||||||
|
.getBlobStore();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListObjectsWhenResponseIs2xx() throws Exception {
|
||||||
|
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder().put(
|
||||||
|
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess).build();
|
||||||
|
|
||||||
|
BlobStore clientWhenServersExist = requestsSendResponses(requestResponseMap);
|
||||||
|
|
||||||
|
Set<? extends Location> locations = clientWhenServersExist.listAssignableLocations();
|
||||||
|
assertNotNull(locations);
|
||||||
|
assertEquals(locations.size(), 1);
|
||||||
|
assertEquals(locations.iterator().next().getId(), "region-a.geo-1");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/**
|
||||||
|
* 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.objectstorage.internal;
|
||||||
|
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.net.HttpHeaders;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.io.Payload;
|
||||||
|
import org.jclouds.util.Strings2;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import static java.lang.String.format;
|
||||||
|
import static org.jclouds.rest.BaseRestClientExpectTest.payloadFromStringWithContentType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for writing HP Cloud Object Storage Rest Client Expect tests
|
||||||
|
*
|
||||||
|
* @author Michael Arnold
|
||||||
|
*/
|
||||||
|
public enum KeystoneFixture {
|
||||||
|
INSTANCE;
|
||||||
|
|
||||||
|
public String getTenantName(){
|
||||||
|
return "12346637803162";
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpRequest initialAuthWithUsernameAndPassword(String username, String password){
|
||||||
|
return HttpRequest
|
||||||
|
.builder()
|
||||||
|
.method("POST")
|
||||||
|
.endpoint(URI.create("https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/tokens"))
|
||||||
|
.headers(ImmutableMultimap.of(HttpHeaders.ACCEPT, "application/json"))
|
||||||
|
.payload(
|
||||||
|
payloadFromStringWithContentType(
|
||||||
|
format(
|
||||||
|
"{\"auth\":{\"passwordCredentials\":{\"username\":\"%s\",\"password\":\"%s\"},\"tenantName\":\"%s\"}}",
|
||||||
|
username, password, getTenantName()), "application/json")).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpRequest initialAuthWithAccessKeyAndSecretKey(String accessKey, String secretKey){
|
||||||
|
return HttpRequest
|
||||||
|
.builder()
|
||||||
|
.method("POST")
|
||||||
|
.endpoint(URI.create("https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/tokens"))
|
||||||
|
.headers(ImmutableMultimap.of(HttpHeaders.ACCEPT, "application/json"))
|
||||||
|
.payload(
|
||||||
|
payloadFromStringWithContentType(
|
||||||
|
format(
|
||||||
|
"{\"auth\":{\"apiAccessKeyCredentials\":{\"accessKey\":\"%s\",\"secretKey\":\"%s\"},\"tenantName\":\"%s\"}}",
|
||||||
|
accessKey, secretKey, getTenantName()), "application/json")).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthToken(){
|
||||||
|
return "Auth_4f173437e4b013bee56d1007";
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponse responseWithAccess(){
|
||||||
|
return HttpResponse.builder().statusCode(200).message("HTTP/1.1 200").payload(
|
||||||
|
payloadFromResourceWithContentType("/keystoneAuthResponse.json", "application/json")).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Payload payloadFromResourceWithContentType(String resource, String contentType) {
|
||||||
|
try {
|
||||||
|
return payloadFromStringWithContentType(Strings2.toStringAndClose(getClass().getResourceAsStream(resource)),
|
||||||
|
contentType);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw Throwables.propagate(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.objectstorage.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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
{
|
||||||
|
"access": {
|
||||||
|
"token": {
|
||||||
|
"expires": "2012-01-18T21:35:59.050Z",
|
||||||
|
"id": "Auth_4f173437e4b013bee56d1007",
|
||||||
|
"tenant": {
|
||||||
|
"id": "40806637803162",
|
||||||
|
"name": "user@jclouds.org-default-tenant"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"id": "36980896575174",
|
||||||
|
"name": "user@jclouds.org",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"id": "00000000004022",
|
||||||
|
"serviceId": "110",
|
||||||
|
"name": "Admin",
|
||||||
|
"tenantName": "40806637803162"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "00000000004024",
|
||||||
|
"serviceId": "140",
|
||||||
|
"name": "user",
|
||||||
|
"tenantName": "40806637803162"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "00000000004004",
|
||||||
|
"serviceId": "100",
|
||||||
|
"name": "domainuser"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "00000000004016",
|
||||||
|
"serviceId": "120",
|
||||||
|
"name": "netadmin",
|
||||||
|
"tenantName": "40806637803162"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"serviceCatalog": [
|
||||||
|
{
|
||||||
|
"name": "Object Storage",
|
||||||
|
"type": "object-store",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"tenantName": "40806637803162",
|
||||||
|
"adminURL": "https://objects.jclouds.org/v1.0/",
|
||||||
|
"publicURL": "https://objects.jclouds.org/v1.0/40806637803162",
|
||||||
|
"region": "region-a.geo-1",
|
||||||
|
"id": "1.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Identity",
|
||||||
|
"type": "identity",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"publicURL": "https://csnode.jclouds.org/v2.0/",
|
||||||
|
"region": "region-a.geo-1",
|
||||||
|
"id": "2.0",
|
||||||
|
"list": "https://csnode.jclouds.org/extension"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Image Management",
|
||||||
|
"type": "image",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"tenantName": "40806637803162",
|
||||||
|
"publicURL": "https://glance.jclouds.org:9292/v1.0",
|
||||||
|
"region": "az-1.region-a.geo-1",
|
||||||
|
"id": "1.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"Cloud Servers",
|
||||||
|
"type":"compute",
|
||||||
|
"endpoints":[{
|
||||||
|
"tenantId":"1",
|
||||||
|
"publicURL":"https://compute.north.host/v1/1234",
|
||||||
|
"internalURL":"https://compute.north.host/v1/1234",
|
||||||
|
"region":"az-1.region-a.geo-1",
|
||||||
|
"versionId":"1.0",
|
||||||
|
"versionInfo":"https://compute.north.host/v1.0/",
|
||||||
|
"versionList":"https://compute.north.host/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tenantId":"2",
|
||||||
|
"publicURL":"https://compute.north.host/v1.1/3456",
|
||||||
|
"internalURL":"https://compute.north.host/v1.1/3456",
|
||||||
|
"region":"az-1.region-a.geo-1",
|
||||||
|
"versionId":"1.1",
|
||||||
|
"versionInfo":"https://compute.north.host/v1.1/",
|
||||||
|
"versionList":"https://compute.north.host/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"endpoints_links":[]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
{
|
||||||
|
"access": {
|
||||||
|
"token": {
|
||||||
|
"expires": "2012-01-18T21:35:59.050Z",
|
||||||
|
"id": "Auth_4f173437e4b013bee56d1007",
|
||||||
|
"tenant": {
|
||||||
|
"id": "40806637803162",
|
||||||
|
"name": "user@jclouds.org-default-tenant"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"id": "36980896575174",
|
||||||
|
"name": "user@jclouds.org",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"id": "00000000004022",
|
||||||
|
"serviceId": "110",
|
||||||
|
"name": "Admin",
|
||||||
|
"tenantName": "40806637803162"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "00000000004024",
|
||||||
|
"serviceId": "140",
|
||||||
|
"name": "user",
|
||||||
|
"tenantName": "40806637803162"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "00000000004004",
|
||||||
|
"serviceId": "100",
|
||||||
|
"name": "domainuser"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "00000000004016",
|
||||||
|
"serviceId": "120",
|
||||||
|
"name": "netadmin",
|
||||||
|
"tenantName": "40806637803162"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"serviceCatalog": [
|
||||||
|
{
|
||||||
|
"name": "CDN",
|
||||||
|
"type": "hpext:cdn",
|
||||||
|
"endpoints": [{
|
||||||
|
"tenantId": "1",
|
||||||
|
"publicURL": "https://cdnmgmt.jclouds.org/v1.0/40806637803162",
|
||||||
|
"region": "region-a.geo-1",
|
||||||
|
"versionId": "1.0",
|
||||||
|
"versionInfo":"https://cdnmgmt.jclouds.org/v1.0/",
|
||||||
|
"versionList":"https://cdnmgmt.jclouds.org"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Object Storage",
|
||||||
|
"type": "object-store",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"tenantName": "40806637803162",
|
||||||
|
"adminURL": "https://objects.jclouds.org/v1.0/",
|
||||||
|
"publicURL": "https://objects.jclouds.org/v1.0/40806637803162",
|
||||||
|
"region": "region-a.geo-1",
|
||||||
|
"id": "1.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Identity",
|
||||||
|
"type": "identity",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"publicURL": "https://csnode.jclouds.org/v2.0/",
|
||||||
|
"region": "region-a.geo-1",
|
||||||
|
"id": "2.0",
|
||||||
|
"list": "https://csnode.jclouds.org/extension"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Image Management",
|
||||||
|
"type": "image",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"tenantName": "40806637803162",
|
||||||
|
"publicURL": "https://glance.jclouds.org:9292/v1.0",
|
||||||
|
"region": "az-1.region-a.geo-1",
|
||||||
|
"id": "1.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"Cloud Servers",
|
||||||
|
"type":"compute",
|
||||||
|
"endpoints":[{
|
||||||
|
"tenantId":"1",
|
||||||
|
"publicURL":"https://compute.north.host/v1/1234",
|
||||||
|
"internalURL":"https://compute.north.host/v1/1234",
|
||||||
|
"region":"az-1.region-a.geo-1",
|
||||||
|
"versionId":"1.0",
|
||||||
|
"versionInfo":"https://compute.north.host/v1.0/",
|
||||||
|
"versionList":"https://compute.north.host/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tenantId":"2",
|
||||||
|
"publicURL":"https://compute.north.host/v1.1/3456",
|
||||||
|
"internalURL":"https://compute.north.host/v1.1/3456",
|
||||||
|
"region":"az-1.region-a.geo-1",
|
||||||
|
"versionId":"1.1",
|
||||||
|
"versionInfo":"https://compute.north.host/v1.1/",
|
||||||
|
"versionList":"https://compute.north.host/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"endpoints_links":[]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>
|
|
@ -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"}
|
||||||
|
]
|
|
@ -40,5 +40,7 @@
|
||||||
<module>elb</module>
|
<module>elb</module>
|
||||||
<module>aws-elb</module>
|
<module>aws-elb</module>
|
||||||
<module>savvis-symphonyvpdc</module>
|
<module>savvis-symphonyvpdc</module>
|
||||||
|
<module>hpcloud-objectstorage</module>
|
||||||
|
<module>hpcloud-compute</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
||||||
|
|
Loading…
Reference in New Issue