Dedupe code between google cloud products.

This commit is contained in:
Adrian Cole 2014-11-13 10:00:30 -08:00
parent 4213fcb4e1
commit 6e30fc611a
38 changed files with 454 additions and 408 deletions

View File

@ -1,15 +1,18 @@
jclouds Google Cloud Storage Provider
===========================================================
======
Make sure both Google Cloud Storage and Google Cloud Storage JSON API are enabled for the project
(check from Developers Console -> Api&auth -> APIs)
* Q. What is the identity for GCE?
FAQ:
--------
A. the identity is the developer email which can be obtained from the admin GUI. Its usually something in the form: <my account id>@developer.gserviceaccount.com
* Q. What is the identity for Google Cloud Storage?
* Q. What is the credential for GCE
A. the identity is the developer email which can be obtained from the admin GUI. Its usually something in the form: [PROJECT_ID](https://cloud.google.com/compute/docs/overview#projectids)@developer.gserviceaccount.com
A. the credential is a private key, in pem format. It can be extracted from the p12 keystore that is obtained when creating a "Service Account" (in the GUI: Developers Console(For the project) -> APIs and Auth -> Create New Client ID -> "Service Account"
* Q. What is the credential for Google Cloud Storage
A. the credential is a private key, in pem format. It can be extracted from the p12 keystore that is obtained when creating a "Service Account" (in the GUI: Google apis console > Api Access > Create another client ID > "Service Account"
* Q. How to convert a p12 keystore into a pem format jclouds Google Cloud Storage can handle:
@ -25,23 +28,24 @@ The last file (<my_key>.pem) should contain the pk that needs to be passed to `C
Running the live tests:
---------------------------------------------------------------
--------
1. Place the following in your ~/.m2/settings.xml in a profile enabled when live:
```
<properties>
<test.google-cloud-storage.identity>Email address associated with service account</test.google-cloud-storage.identity>
<!-- this text is literally from your <my_key>.pem -->
<test.google-cloud-storage.identity>PROJECT_ID@developer.gserviceaccount.com</test.google-cloud-storage.identity>
<test.google-cloud-storage.credential>-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQRRbRqVDtJLN1MO/xJoKqZuphDeBh5jIKueW3aNIiWs1XFcct+h
...
-- this text is literally from your <my_key>.pem
aH7xmpHSTbbXmQkuuv+z8EKijigprd/FoJpTX1f5/R+4wQ==
-----END RSA PRIVATE KEY-----</test.google-cloud-storage.credential>
<test.google-cloud-storage.project-number>123451234</test.google-cloud-storage.project-number>
</properties>
</properties>
```
Or, if using an existing OAuth Bearer Token for authentication.
```
<test.google-cloud-storage.identity>PROJECT_ID@developer.gserviceaccount.com</test.google-cloud-storage.identity>
<test.google-cloud-storage.credential>EXISTING_BEARER_TOKEN</test.google-cloud-storage.credential>
<test.jclouds.oauth.credential-type>bearerTokenCredentials</test.jclouds.oauth.credential-type>
</properties>
```
Example identity :- 123451234-abcd01234efgh@developer.gserviceaccount.com (NUMERIC_PREFIX-ALPHANEUMERIC_SUFFIX@developer.gserviceaccount.com)
2. mvn integration-test -pl google-cloud-storage -Plive
2. mvn clean install -Plive

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
@ -14,131 +15,137 @@
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>
<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.apache.jclouds.labs</groupId>
<artifactId>jclouds-labs-google</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>
<!-- TODO: when out of labs, switch to org.jclouds.provider -->
<groupId>org.apache.jclouds.labs</groupId>
<artifactId>jclouds-labs-google</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>
<!-- TODO: when out of labs, switch to org.jclouds.provider -->
<groupId>org.apache.jclouds.labs</groupId>
<artifactId>google-cloud-storage</artifactId>
<name>jclouds Google Cloud Storage provider</name>
<description>jclouds components to access Google Cloud Storage</description>
<artifactId>google-cloud-storage</artifactId>
<name>jclouds Google Cloud Storage provider</name>
<description>jclouds components to access Google Cloud Storage</description>
<properties>
<test.google-cloud-storage.identity> Email_Address_Associated_With_Service_Account</test.google-cloud-storage.identity>
<test.google-cloud-storage.credential>Private_Key_Associated__With_Service Account</test.google-cloud-storage.credential>
<test.google-cloud-storage.project-number>The Account Project number</test.google-cloud-storage.project-number>
<test.google-cloud-storage.api-version>v1</test.google-cloud-storage.api-version>
<test.google-cloud-storage.build-version />
</properties>
<properties>
<test.google-cloud-storage.identity>client_email which usually looks like project_id@developer.gserviceaccount.com</test.google-cloud-storage.identity>
<test.google-cloud-storage.credential>Private key (PEM encoded PKCS12 file or literal) associated with the client_email</test.google-cloud-storage.credential>
<!-- Add this property to use a different project, or avoid looking up the project for each test. -->
<test.jclouds.googlecloud.project-name></test.jclouds.googlecloud.project-name>
<test.jclouds.oauth.credential-type>p12PrivateKeyCredentials</test.jclouds.oauth.credential-type>
<test.google-cloud-storage.api-version>v1</test.google-cloud-storage.api-version>
<test.google-cloud-storage.build-version/>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${jclouds.version}</version>
</dependency>
<dependency>
<groupId>org.apache.jclouds.labs</groupId>
<artifactId>oauth</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.jclouds.labs</groupId>
<artifactId>oauth</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-blobstore</artifactId>
<version>${jclouds.version}</version>
</dependency>
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-blobstore</artifactId>
<version>${jclouds.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${jclouds.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.jclouds.driver</groupId>
<artifactId>jclouds-slf4j</artifactId>
<version>${jclouds.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.jclouds.driver</groupId>
<artifactId>jclouds-sshj</artifactId>
<version>${jclouds.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>1.6.1</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>default-test</id>
<configuration>
<skipTests>true</skipTests>
</configuration>
</execution>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemPropertyVariables>
<jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url>
<jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
<test.google-cloud-storage.identity>${test.google-cloud-storage.identity}</test.google-cloud-storage.identity>
<test.google-cloud-storage.credential>${test.google-cloud-storage.credential}</test.google-cloud-storage.credential>
<test.google-cloud-storage.project-number>${test.google-cloud-storage.project-number}</test.google-cloud-storage.project-number>
<test.google-cloud-storage.api-version>${test.google-cloud-storage.api-version}</test.google-cloud-storage.api-version>
<test.google-cloud-storage.build-version>${test.google-cloud-storage.build-version}</test.google-cloud-storage.build-version>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${jclouds.version}</version>
</dependency>
<dependency>
<groupId>org.apache.jclouds.labs</groupId>
<artifactId>googlecloud</artifactId>
<version>${project.version}</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.jclouds.labs</groupId>
<artifactId>googlecloud</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-blobstore</artifactId>
<version>${jclouds.version}</version>
</dependency>
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-blobstore</artifactId>
<version>${jclouds.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${jclouds.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.jclouds.driver</groupId>
<artifactId>jclouds-slf4j</artifactId>
<version>${jclouds.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>mockwebserver</artifactId>
<scope>test</scope>
<exclusions>
<!-- Already provided by jclouds-sshj -->
<exclusion>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>default-test</id>
<configuration>
<skipTests>true</skipTests>
</configuration>
</execution>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.google-cloud-storage.identity>${test.google-cloud-storage.identity}</test.google-cloud-storage.identity>
<test.google-cloud-storage.credential>${test.google-cloud-storage.credential}</test.google-cloud-storage.credential>
<test.jclouds.googlecloud.project-name>${test.jclouds.googlecloud.project-name}</test.jclouds.googlecloud.project-name>
<test.jclouds.oauth.credential-type>${test.jclouds.oauth.credential-type}</test.jclouds.oauth.credential-type>
<test.google-cloud-storage.api-version>${test.google-cloud-storage.api-version}</test.google-cloud-storage.api-version>
<test.google-cloud-storage.build-version>${test.google-cloud-storage.build-version}</test.google-cloud-storage.build-version>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -17,7 +17,6 @@
package org.jclouds.googlecloudstorage;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.googlecloudstorage.reference.GoogleCloudStorageConstants.GCS_PROVIDER_NAME;
import static org.jclouds.googlecloudstorage.reference.GoogleCloudStorageConstants.OPERATION_COMPLETE_INTERVAL;
import static org.jclouds.googlecloudstorage.reference.GoogleCloudStorageConstants.OPERATION_COMPLETE_TIMEOUT;
import static org.jclouds.oauth.v2.config.OAuthProperties.AUDIENCE;
@ -27,20 +26,18 @@ import static org.jclouds.reflect.Reflection2.typeToken;
import java.net.URI;
import java.util.Properties;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.googlecloudstorage.blobstore.config.GCSBlobStoreContextModule;
import org.jclouds.googlecloud.config.CurrentProject;
import org.jclouds.googlecloudstorage.blobstore.config.GoogleCloudStorageBlobStoreContextModule;
import org.jclouds.googlecloudstorage.config.GoogleCloudStorageHttpApiModule;
import org.jclouds.googlecloudstorage.config.GoogleCloudStorageParserModule;
import org.jclouds.oauth.v2.config.OAuthAuthenticationModule;
import org.jclouds.oauth.v2.config.OAuthModule;
import org.jclouds.rest.internal.BaseHttpApiMetadata;
import com.google.auto.service.AutoService;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
@AutoService(ApiMetadata.class)
public class GoogleCloudStorageApiMetadata extends BaseHttpApiMetadata<GoogleCloudStorageApi> {
@Override
@ -69,20 +66,21 @@ public class GoogleCloudStorageApiMetadata extends BaseHttpApiMetadata<GoogleClo
public static class Builder extends BaseHttpApiMetadata.Builder<GoogleCloudStorageApi, Builder> {
protected Builder() {
id(GCS_PROVIDER_NAME)
.name("Google Cloud Storage Api ")
.identityName("Email associated with the Google API client_id")
.credentialName("Private key literal associated with the Google API client_id")
.documentation(URI.create("https://developers.google.com/storage/docs/json_api"))
.version("v1")
.defaultEndpoint("https://www.googleapis.com")
.defaultProperties(GoogleCloudStorageApiMetadata.defaultProperties())
.view(typeToken(BlobStoreContext.class))
.defaultModules(
ImmutableSet.<Class<? extends Module>> of(GoogleCloudStorageParserModule.class,
OAuthAuthenticationModule.class, OAuthModule.class,
GoogleCloudStorageHttpApiModule.class, GCSBlobStoreContextModule.class));
id("google-cloud-storage")
.name("Google Cloud Storage Api")
.identityName(CurrentProject.ClientEmail.DESCRIPTION)
.credentialName("PEM encoded P12 private key associated with client_email")
.documentation(URI.create("https://developers.google.com/storage/docs/json_api"))
.version("v1")
.defaultEndpoint("https://www.googleapis.com")
.defaultProperties(GoogleCloudStorageApiMetadata.defaultProperties())
.view(typeToken(BlobStoreContext.class))
.defaultModules(ImmutableSet.<Class<? extends Module>> builder()
.add(GoogleCloudStorageParserModule.class)
.add(OAuthAuthenticationModule.class)
.add(OAuthModule.class)
.add(GoogleCloudStorageHttpApiModule.class)
.add(GoogleCloudStorageBlobStoreContextModule.class).build());
}
@Override

View File

@ -18,14 +18,8 @@ package org.jclouds.googlecloudstorage;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
import static org.jclouds.Fallbacks.valOnNotFoundOr404;
import java.util.Iterator;
import org.jclouds.Fallback;
import org.jclouds.googlecloudstorage.domain.ListPage;
import com.google.common.collect.Iterators;
public final class GoogleCloudStorageFallbacks {
@ -37,16 +31,4 @@ public final class GoogleCloudStorageFallbacks {
throw propagate(t);
}
}
public static final class EmptyListPageOnNotFoundOr404 implements Fallback<Object> {
@Override public ListPage<Object> createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(ListPage.create(null, null, null), t);
}
}
public static final class EmptyIteratorOnNotFoundOr404 implements Fallback<Object> {
@Override public Iterator<Object> createOrPropagate(Throwable t) throws Exception {
return valOnNotFoundOr404(Iterators.emptyIterator(), t);
}
}
}

View File

@ -0,0 +1,72 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.googlecloudstorage;
import java.net.URI;
import java.util.Properties;
import org.jclouds.providers.ProviderMetadata;
import org.jclouds.providers.internal.BaseProviderMetadata;
import com.google.auto.service.AutoService;
/** Note: This does not set iso3166Codes as Google intentionally does not document them. */
@AutoService(ProviderMetadata.class)
public final class GoogleCloudStorageProviderMetadata extends BaseProviderMetadata {
public static Builder builder() {
return new Builder();
}
@Override
public Builder toBuilder() {
return builder().fromProviderMetadata(this);
}
public GoogleCloudStorageProviderMetadata() {
super(builder());
}
public GoogleCloudStorageProviderMetadata(Builder builder) {
super(builder);
}
public static Properties defaultProperties() {
return new Properties(); // currently all are set in the api metadata class.
}
public static final class Builder extends BaseProviderMetadata.Builder {
private Builder() {
id("google-cloud-storage") //
.name("Google Cloud Storage") //
.apiMetadata(new GoogleCloudStorageApiMetadata()) //
.homepage(URI.create("https://cloud.google.com/storage")) //
.console(URI.create("https://console.developers.google.com/project")) //
.defaultProperties(GoogleCloudStorageProviderMetadata.defaultProperties());
}
@Override public GoogleCloudStorageProviderMetadata build() {
return new GoogleCloudStorageProviderMetadata(this);
}
@Override public Builder fromProviderMetadata(ProviderMetadata in) {
super.fromProviderMetadata(in);
return this;
}
}
}

View File

@ -43,6 +43,8 @@ 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.googlecloud.config.CurrentProject;
import org.jclouds.googlecloud.domain.ListPage;
import org.jclouds.googlecloudstorage.GoogleCloudStorageApi;
import org.jclouds.googlecloudstorage.blobstore.functions.BlobMetadataToObjectTemplate;
import org.jclouds.googlecloudstorage.blobstore.functions.BlobStoreListContainerOptionsToListObjectOptions;
@ -50,11 +52,10 @@ import org.jclouds.googlecloudstorage.blobstore.functions.BucketToStorageMetadat
import org.jclouds.googlecloudstorage.blobstore.functions.ObjectListToStorageMetadata;
import org.jclouds.googlecloudstorage.blobstore.functions.ObjectToBlobMetadata;
import org.jclouds.googlecloudstorage.blobstore.strategy.internal.MultipartUploadStrategy;
import org.jclouds.googlecloudstorage.config.UserProject;
import org.jclouds.googlecloudstorage.domain.Bucket;
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences;
import org.jclouds.googlecloudstorage.domain.GCSObject;
import org.jclouds.googlecloudstorage.domain.ListPage;
import org.jclouds.googlecloudstorage.domain.ListPageWithPrefixes;
import org.jclouds.googlecloudstorage.domain.templates.BucketTemplate;
import org.jclouds.googlecloudstorage.domain.templates.ObjectAccessControlsTemplate;
import org.jclouds.googlecloudstorage.domain.templates.ObjectTemplate;
@ -89,7 +90,7 @@ public final class GCSBlobStore extends BaseBlobStore {
Provider<FetchBlobMetadata> fetchBlobMetadataProvider,
BlobMetadataToObjectTemplate blobMetadataToObjectTemplate,
BlobStoreListContainerOptionsToListObjectOptions listContainerOptionsToListObjectOptions,
MultipartUploadStrategy multipartUploadStrategy, @UserProject Supplier<String> projectId) {
MultipartUploadStrategy multipartUploadStrategy, @CurrentProject Supplier<String> projectId) {
super(context, blobUtils, defaultLocation, locations);
this.api = api;
this.bucketToStorageMetadata = bucketToStorageMetadata;
@ -152,7 +153,7 @@ public final class GCSBlobStore extends BaseBlobStore {
/** Returns list of of all the objects */
@Override
public PageSet<? extends StorageMetadata> list(String container) {
ListPage<GCSObject> gcsList = api.getObjectApi().listObjects(container);
ListPageWithPrefixes<GCSObject> gcsList = api.getObjectApi().listObjects(container);
PageSet<? extends StorageMetadata> list = objectListToStorageMetadata.apply(gcsList);
return list;
}
@ -161,7 +162,7 @@ public final class GCSBlobStore extends BaseBlobStore {
public PageSet<? extends StorageMetadata> list(String container, ListContainerOptions options) {
if (options != null && options != ListContainerOptions.NONE) {
ListObjectOptions listOptions = listContainerOptionsToListObjectOptions.apply(options);
ListPage<GCSObject> gcsList = api.getObjectApi().listObjects(container, listOptions);
ListPageWithPrefixes<GCSObject> gcsList = api.getObjectApi().listObjects(container, listOptions);
PageSet<? extends StorageMetadata> list = objectListToStorageMetadata.apply(gcsList);
return options.isDetailed() ? fetchBlobMetadataProvider.get().setContainerName(container).apply(list) : list;
} else {
@ -241,7 +242,7 @@ public final class GCSBlobStore extends BaseBlobStore {
@Override
protected boolean deleteAndVerifyContainerGone(String container) {
ListPage<GCSObject> list = api.getObjectApi().listObjects(container);
ListPageWithPrefixes<GCSObject> list = api.getObjectApi().listObjects(container);
if (list == null) {
return api.getBucketApi().deleteBucket(container);
}

View File

@ -16,13 +16,14 @@
*/
package org.jclouds.googlecloudstorage.blobstore.config;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.attr.ConsistencyModel;
import org.jclouds.googlecloudstorage.blobstore.GCSBlobStore;
public class GCSBlobStoreContextModule extends AbstractModule {
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
public class GoogleCloudStorageBlobStoreContextModule extends AbstractModule {
@Override
protected void configure() {

View File

@ -27,22 +27,23 @@ import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.PageSetImpl;
import org.jclouds.blobstore.domain.internal.StorageMetadataImpl;
import org.jclouds.googlecloudstorage.domain.GCSObject;
import org.jclouds.googlecloudstorage.domain.ListPage;
import org.jclouds.googlecloudstorage.domain.ListPageWithPrefixes;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
public class ObjectListToStorageMetadata implements Function<ListPage<GCSObject>, PageSet<? extends StorageMetadata>> {
public class ObjectListToStorageMetadata
implements Function<ListPageWithPrefixes<GCSObject>, PageSet<? extends StorageMetadata>> {
private final ObjectToBlobMetadata object2blobMd;
@Inject public ObjectListToStorageMetadata(ObjectToBlobMetadata object2blobMd) {
this.object2blobMd = object2blobMd;
}
public PageSet<? extends StorageMetadata> apply(ListPage<GCSObject> from) {
public PageSet<? extends StorageMetadata> apply(ListPageWithPrefixes<GCSObject> from) {
if (from == null) {
from = ListPage.create(null, null, null);
from = ListPageWithPrefixes.create(null, null, null);
}
return new PageSetImpl<StorageMetadata>(Iterables.transform(Iterables.transform(from, object2blobMd),

View File

@ -16,13 +16,14 @@
*/
package org.jclouds.googlecloudstorage.blobstore.strategy.internal;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import javax.annotation.Resource;
import javax.inject.Named;
import org.jclouds.blobstore.reference.BlobStoreConstants;
import org.jclouds.logging.Logger;
import javax.annotation.Resource;
import javax.inject.Named;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
public class MultipartUploadSlicingAlgorithm {

View File

@ -16,16 +16,10 @@
*/
package org.jclouds.googlecloudstorage.config;
import static com.google.common.base.Suppliers.compose;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.domain.Credentials;
import org.jclouds.googlecloud.config.CurrentProject;
import org.jclouds.googlecloudstorage.GoogleCloudStorageApi;
import org.jclouds.googlecloudstorage.handlers.GoogleCloudStorageErrorHandler;
import org.jclouds.http.HttpErrorHandler;
@ -34,15 +28,12 @@ import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.location.Provider;
import org.jclouds.oauth.v2.config.OAuthScopes;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.config.HttpApiModule;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
import com.google.common.base.Suppliers;
import com.google.inject.Provides;
@ConfiguresHttpApi
@ -61,25 +52,12 @@ public class GoogleCloudStorageHttpApiModule extends HttpApiModule<GoogleCloudSt
}
@Provides
@Singleton
@UserProject
public Supplier<String> supplyProject(@Provider final Supplier<Credentials> creds, final GoogleCloudStorageApi api,
AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds) {
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
compose(new Function<Credentials, String>() {
public String apply(Credentials in) {
// ID should be of the form project_id@developer.gserviceaccount.com
// OR (increasingly often) project_id-extended_uid@developer.gserviceaccount.com
String projectName = in.identity;
if (projectName.indexOf("@") != -1) {
projectName = Iterables.get(Splitter.on("@").split(projectName), 0);
if (projectName.indexOf("-") != -1) {
// if ID is of the form project_id-extended_uid@developer.gserviceaccount.com
projectName = Iterables.get(Splitter.on("-").split(projectName), 0);
}
}
return projectName;
}
}, creds), seconds, TimeUnit.SECONDS);
@Singleton @CurrentProject
public Supplier<String> supplyProject(@Provider final Supplier<Credentials> creds) {
return Suppliers.compose(new Function<Credentials, String>() {
@Override public String apply(Credentials in) {
return CurrentProject.ClientEmail.toProjectNumber(in.identity);
}
}, creds);
}
}

View File

@ -18,17 +18,21 @@ package org.jclouds.googlecloudstorage.config;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Set;
import javax.inject.Singleton;
import org.jclouds.googlecloud.config.ListPageAdapterFactory;
import org.jclouds.googlecloudstorage.domain.templates.BucketTemplate;
import org.jclouds.json.config.GsonModule;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.TypeAdapterFactory;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@ -44,6 +48,11 @@ public class GoogleCloudStorageParserModule extends AbstractModule {
.build();
}
// TODO: change jclouds core to use collaborative set bindings
@Provides @Singleton Set<TypeAdapterFactory> typeAdapterFactories() {
return ImmutableSet.<TypeAdapterFactory>of(new ListPageAdapterFactory());
}
private static class BucketTemplateTypeAdapter implements JsonSerializer<BucketTemplate> {
@Override

View File

@ -1,33 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.googlecloudstorage.config;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
* Qualifies a property as the user's project id.
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Qualifier
public @interface UserProject {
}

View File

@ -17,7 +17,7 @@
package org.jclouds.googlecloudstorage.domain;
import static org.jclouds.googlecloudstorage.internal.NullSafeCopies.copyOf;
import static org.jclouds.googlecloud.internal.NullSafeCopies.copyOf;
import java.util.Date;
import java.util.List;
@ -151,7 +151,7 @@ public abstract class Bucket {
public abstract List<ObjectAccessControls> defaultObjectAcl();
public abstract Owner owner();
@Nullable public abstract Owner owner();
@Nullable public abstract Location location();

View File

@ -17,7 +17,7 @@
package org.jclouds.googlecloudstorage.domain;
import static org.jclouds.googlecloudstorage.internal.NullSafeCopies.copyOf;
import static org.jclouds.googlecloud.internal.NullSafeCopies.copyOf;
import java.net.URI;
import java.util.Date;

View File

@ -16,34 +16,35 @@
*/
package org.jclouds.googlecloudstorage.domain;
import static org.jclouds.googlecloudstorage.internal.NullSafeCopies.copyOf;
import static org.jclouds.googlecloud.internal.NullSafeCopies.copyOf;
import java.beans.ConstructorProperties;
import java.util.List;
import org.jclouds.googlecloud.domain.ListPage;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.collect.ForwardingList;
/** An immutable list that includes a token, if there is another page available. */
public final class ListPage<T> extends ForwardingList<T> {
public final class ListPageWithPrefixes<T> extends ForwardingList<T> implements ListPage<T> {
private final List<T> items;
private final String nextPageToken;
private final List<String> prefixes;
public static <T> ListPage<T> create(List<T> items, String nextPageToken, List<String> prefixes) {
return new ListPage<T>(items, nextPageToken, prefixes);
public static <T> ListPageWithPrefixes<T> create(List<T> items, String nextPageToken, List<String> prefixes) {
return new ListPageWithPrefixes<T>(items, nextPageToken, prefixes);
}
@ConstructorProperties({ "items", "nextPageToken", "prefixes" })
ListPage(List<T> items, String nextPageToken, List<String> prefixes) {
ListPageWithPrefixes(List<T> items, String nextPageToken, List<String> prefixes) {
this.items = copyOf(items);
this.nextPageToken = nextPageToken;
this.prefixes = copyOf(prefixes);
}
@Nullable public String nextPageToken() {
@Override @Nullable public String nextPageToken() {
return nextPageToken;
}

View File

@ -33,10 +33,9 @@ import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.TrueOnNotFoundOr404;
import org.jclouds.blobstore.BlobStoreFallbacks.NullOnKeyAlreadyExists;
import org.jclouds.googlecloudstorage.GoogleCloudStorageFallbacks.EmptyListPageOnNotFoundOr404;
import org.jclouds.googlecloud.domain.ListPage;
import org.jclouds.googlecloudstorage.GoogleCloudStorageFallbacks.NullOnBucketAlreadyExists;
import org.jclouds.googlecloudstorage.domain.Bucket;
import org.jclouds.googlecloudstorage.domain.ListPage;
import org.jclouds.googlecloudstorage.domain.templates.BucketTemplate;
import org.jclouds.googlecloudstorage.options.DeleteBucketOptions;
import org.jclouds.googlecloudstorage.options.GetBucketOptions;
@ -185,7 +184,6 @@ public interface BucketApi {
@GET
@Produces(APPLICATION_JSON)
@Path("/b")
@Fallback(EmptyListPageOnNotFoundOr404.class)
ListPage<Bucket> listBucket(@QueryParam("project") String projectId);
/**
@ -200,7 +198,6 @@ public interface BucketApi {
@GET
@Produces(APPLICATION_JSON)
@Path("/b")
@Fallback(EmptyListPageOnNotFoundOr404.class)
ListPage<Bucket> listBucket(@QueryParam("project") String projectId, ListOptions options);
/**

View File

@ -32,11 +32,10 @@ import javax.ws.rs.Produces;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.TrueOnNotFoundOr404;
import org.jclouds.googlecloudstorage.GoogleCloudStorageFallbacks.EmptyListPageOnNotFoundOr404;
import org.jclouds.googlecloudstorage.binders.MultipartUploadBinder;
import org.jclouds.googlecloudstorage.binders.UploadBinder;
import org.jclouds.googlecloudstorage.domain.GCSObject;
import org.jclouds.googlecloudstorage.domain.ListPage;
import org.jclouds.googlecloudstorage.domain.ListPageWithPrefixes;
import org.jclouds.googlecloudstorage.domain.templates.ComposeObjectTemplate;
import org.jclouds.googlecloudstorage.domain.templates.ObjectTemplate;
import org.jclouds.googlecloudstorage.options.ComposeObjectOptions;
@ -212,7 +211,7 @@ public interface ObjectApi {
* @param objectName
* Name of the object
* @param options
* Supply {@link DeletObjectOptions} with optional query parameters
* Supply {@link DeleteObjectOptions} with optional query parameters
*/
@Named("Object:delete")
@DELETE
@ -226,15 +225,12 @@ public interface ObjectApi {
*
* @param bucketName
* Name of the bucket in which to look for objects.
*
* @return a {@link ListPage<Object>}
*/
@Named("Object:list")
@GET
@Consumes(APPLICATION_JSON)
@Path("storage/v1/b/{bucket}/o")
@Fallback(EmptyListPageOnNotFoundOr404.class)
ListPage<GCSObject> listObjects(@PathParam("bucket") String bucketName);
ListPageWithPrefixes<GCSObject> listObjects(@PathParam("bucket") String bucketName);
/**
* Retrieves a list of objects matching the criteria.
@ -249,8 +245,7 @@ public interface ObjectApi {
@GET
@Consumes(APPLICATION_JSON)
@Path("storage/v1/b/{bucket}/o")
@Fallback(EmptyListPageOnNotFoundOr404.class)
ListPage<GCSObject> listObjects(@PathParam("bucket") String bucketName, ListObjectOptions options);
ListPageWithPrefixes<GCSObject> listObjects(@PathParam("bucket") String bucketName, ListObjectOptions options);
/**
* Updates an object metadata

View File

@ -22,6 +22,7 @@ import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
import org.jclouds.http.handlers.RedirectionRetryHandler;
import com.google.inject.Inject;
/**

View File

@ -1,39 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.googlecloudstorage.internal;
import java.util.List;
import java.util.Map;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
public class NullSafeCopies {
public static <K, V> Map<K, V> copyOf(@Nullable Map<K, V> map) {
return map != null ? ImmutableMap.copyOf(map) : ImmutableMap.<K, V>of();
}
public static <E> List<E> copyOf(@Nullable List<E> list) {
return list != null ? ImmutableList.copyOf(list) : ImmutableList.<E>of();
}
private NullSafeCopies() {
}
}

View File

@ -19,18 +19,16 @@ package org.jclouds.googlecloudstorage.options;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.Projection;
import org.jclouds.http.options.BaseHttpRequestOptions;
public class ListOptions extends BaseHttpRequestOptions {
public class ListOptions extends org.jclouds.googlecloud.options.ListOptions {
public ListOptions pageToken(String pageToken) {
this.queryParameters.put("pageToken", checkNotNull(pageToken, "pageToken"));
return this;
}
public ListOptions maxResults(Integer maxResults) {
this.queryParameters.put("maxResults", checkNotNull(maxResults, "maxResults") + "");
return this;
@Override public ListOptions maxResults(Integer maxResults) {
return (ListOptions) super.maxResults(maxResults);
}
public ListOptions projection(Projection projection) {

View File

@ -18,6 +18,7 @@ package org.jclouds.googlecloudstorage.parser;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.internal.PayloadEnclosingImpl;
import com.google.common.base.Function;
public class ParseToPayloadEnclosing implements Function<HttpResponse, PayloadEnclosingImpl> {

View File

@ -23,8 +23,6 @@ public final class GoogleCloudStorageConstants {
private GoogleCloudStorageConstants() {
}
public static final String GCS_PROVIDER_NAME = "google-cloud-storage";
/**
* The total time, in msecs, to wait for an operation to complete.
*/

View File

@ -1,31 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.googlecloudstorage;
import org.jclouds.View;
import org.jclouds.apis.internal.BaseApiMetadataTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
@Test(groups = "unit", testName = "GoogleStorageApiMetadataTest")
public class GoogleCloudStorageApiMetadataTest extends BaseApiMetadataTest {
public GoogleCloudStorageApiMetadataTest() {
super(new GoogleCloudStorageApiMetadata(), ImmutableSet.<TypeToken<? extends View>> of());
}
}

View File

@ -16,19 +16,19 @@
*/
package org.jclouds.googlecloudstorage;
import org.jclouds.oauth.v2.internal.BaseOAuthAuthenticatedApiLiveTest;
import org.jclouds.providers.internal.BaseProviderMetadataTest;
import org.testng.annotations.Test;
@Test(groups = "live")
public class GoogleCloudStorageAuthenticatedRestContextLiveTest extends
BaseOAuthAuthenticatedApiLiveTest<GoogleCloudStorageApi> {
public GoogleCloudStorageAuthenticatedRestContextLiveTest() {
provider = "google-cloud-storage";
}
@Override
public String getScopes() {
return "https://www.googleapis.com/auth/devstorage.full_control";
/**
* Tests that GoogleComputeProviderMetadata is properly registered in ServiceLoader
* <p/>
* <pre>
* META-INF/services/org.jclouds.providers.ProviderMetadata
* </pre>
*/
@Test(groups = "unit", testName = "GoogleCloudStorageProviderMetadataTest")
public class GoogleCloudStorageProviderMetadataTest extends BaseProviderMetadataTest {
public GoogleCloudStorageProviderMetadataTest() {
super(new GoogleCloudStorageProviderMetadata(), new GoogleCloudStorageApiMetadata());
}
}

View File

@ -16,12 +16,12 @@
*/
package org.jclouds.googlecloudstorage.blobstore.integration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.File;
import java.io.IOException;
@ -37,6 +37,7 @@ import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.googlecloud.internal.TestProperties;
import org.jclouds.googlecloudstorage.blobstore.strategy.internal.MultipartUpload;
import org.jclouds.io.Payloads;
import org.jclouds.io.payloads.ByteSourcePayload;
@ -58,17 +59,16 @@ public class GCSBlobIntegrationLiveTest extends BaseBlobIntegrationTest {
private long PART_SIZE = MultipartUpload.MIN_PART_SIZE;
@Override
protected Properties setupProperties() {
Properties properties = super.setupProperties();
properties.put("jclouds.mpu.parts.size", 2 * 1024 * 1024);
return properties;
}
public GCSBlobIntegrationLiveTest() throws IOException {
provider = "google-cloud-storage";
}
@Override protected Properties setupProperties() {
Properties properties = super.setupProperties();
properties.put("jclouds.mpu.parts.size", 2 * 1024 * 1024);
return TestProperties.apply(provider, properties);
}
@Override
@Test(enabled = false)
public void testGetTwoRanges() throws SkipException {

View File

@ -21,10 +21,12 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.io.IOException;
import java.util.Properties;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.integration.internal.BaseBlobLiveTest;
import org.jclouds.googlecloud.internal.TestProperties;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.internal.PayloadEnclosingImpl;
@ -50,6 +52,10 @@ public class GCSBlobLiveTest extends BaseBlobLiveTest {
provider = "google-cloud-storage";
}
@Override protected Properties setupProperties() {
return TestProperties.apply(provider, super.setupProperties());
}
@Override
@Parameters({ "jclouds.blobstore.httpstream.url", "jclouds.blobstore.httpstream.md5" })
public void testCopyUrl(String httpStreamUrl, String httpStreamMD5) throws Exception {

View File

@ -22,6 +22,7 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import java.io.IOException;
import java.util.Properties;
import javax.ws.rs.core.MediaType;
@ -30,6 +31,7 @@ import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.googlecloud.internal.TestProperties;
import org.testng.SkipException;
import org.testng.annotations.Test;
@ -43,6 +45,10 @@ public class GCSContainerIntegrationLiveTest extends BaseContainerIntegrationTes
provider = "google-cloud-storage";
}
@Override protected Properties setupProperties() {
return TestProperties.apply(provider, super.setupProperties());
}
@Override
@Test(groups = { "integration", "live" })
public void testWithDetails() throws InterruptedException, IOException {
@ -93,5 +99,4 @@ public class GCSContainerIntegrationLiveTest extends BaseContainerIntegrationTes
// GCS does not support directories, rather it supports prefixes which look like directories.
throw new SkipException("directories are not supported in GCS");
}
}

View File

@ -16,7 +16,10 @@
*/
package org.jclouds.googlecloudstorage.blobstore.integration;
import java.util.Properties;
import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest;
import org.jclouds.googlecloud.internal.TestProperties;
import org.testng.annotations.Test;
@Test(groups = { "live" })
@ -25,4 +28,8 @@ public class GCSContainerLiveTest extends BaseContainerLiveTest {
public GCSContainerLiveTest() {
provider = "google-cloud-storage";
}
@Override protected Properties setupProperties() {
return TestProperties.apply(provider, super.setupProperties());
}
}

View File

@ -118,8 +118,9 @@ public class BucketApiExpectTest extends BaseGoogleCloudStorageApiExpectTest {
}
public void testListBucketResponseIs4xx() throws Exception {
HttpResponse listResponse = HttpResponse.builder().statusCode(404).build();
@Test(enabled = false)
public void listBucketEmpty() throws Exception {
HttpResponse listResponse = null; // TODO: get a copy of an empty bucket response
BucketApi api = requestsSendResponses(requestForScopes(STORAGE_READONLY_SCOPE), TOKEN_RESPONSE,
LIST_BUCKET_REQUEST, listResponse).getBucketApi();

View File

@ -26,6 +26,7 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.jclouds.googlecloud.domain.ListPage;
import org.jclouds.googlecloudstorage.domain.Bucket;
import org.jclouds.googlecloudstorage.domain.Bucket.Cors;
import org.jclouds.googlecloudstorage.domain.Bucket.Logging;
@ -36,7 +37,6 @@ import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.Location;
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.ObjectRole;
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.Projection;
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.StorageClass;
import org.jclouds.googlecloudstorage.domain.ListPage;
import org.jclouds.googlecloudstorage.domain.ObjectAccessControls;
import org.jclouds.googlecloudstorage.domain.templates.BucketTemplate;
import org.jclouds.googlecloudstorage.internal.BaseGoogleCloudStorageApiLiveTest;
@ -182,7 +182,6 @@ public class BucketApiLiveTest extends BaseGoogleCloudStorageApiLiveTest {
assertNotNull(iteratedBucket);
assertSame(bucketAsList.size(), 1);
}
@Test(groups = "live", dependsOnMethods = "testCreateBucket")

View File

@ -33,7 +33,7 @@ import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.Destinatio
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.ObjectRole;
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.Projection;
import org.jclouds.googlecloudstorage.domain.GCSObject;
import org.jclouds.googlecloudstorage.domain.ListPage;
import org.jclouds.googlecloudstorage.domain.ListPageWithPrefixes;
import org.jclouds.googlecloudstorage.domain.ObjectAccessControls;
import org.jclouds.googlecloudstorage.domain.templates.BucketTemplate;
import org.jclouds.googlecloudstorage.domain.templates.ComposeObjectTemplate;
@ -262,7 +262,7 @@ public class ObjectApiLiveTest extends BaseGoogleCloudStorageApiLiveTest {
@Test(groups = "live", dependsOnMethods = "testComposeObjectWithOptions")
public void listObjects() {
ListPage<GCSObject> list = api().listObjects(BUCKET_NAME);
ListPageWithPrefixes<GCSObject> list = api().listObjects(BUCKET_NAME);
assertNotNull(list);
assertEquals(list.get(0) instanceof GCSObject, true);
@ -271,7 +271,7 @@ public class ObjectApiLiveTest extends BaseGoogleCloudStorageApiLiveTest {
@Test(groups = "live", dependsOnMethods = "testComposeObjectWithOptions")
public void testListObjectsWithOptions() {
ListObjectOptions options = new ListObjectOptions().maxResults(1);
ListPage<GCSObject> list = api().listObjects(BUCKET_NAME, options);
ListPageWithPrefixes<GCSObject> list = api().listObjects(BUCKET_NAME, options);
while (list.nextPageToken() != null) {
assertNotNull(list);

View File

@ -22,8 +22,7 @@ import org.jclouds.googlecloudstorage.GoogleCloudStorageApi;
public class BaseGoogleCloudStorageApiExpectTest extends BaseGoogleCloudStorageExpectTest<GoogleCloudStorageApi> {
@Override
protected Properties setupProperties() {
@Override protected Properties setupProperties() {
Properties properties = super.setupProperties();
properties.put("google-cloud-storage.identity", "JcloudTest");
return properties;

View File

@ -19,7 +19,11 @@ package org.jclouds.googlecloudstorage.internal;
import java.util.Properties;
import org.jclouds.apis.BaseApiLiveTest;
import org.jclouds.googlecloud.internal.TestProperties;
import org.jclouds.googlecloudstorage.GoogleCloudStorageApi;
import org.jclouds.googlecloudstorage.GoogleCloudStorageProviderMetadata;
import org.jclouds.providers.ProviderMetadata;
import com.google.inject.Injector;
import com.google.inject.Module;
@ -27,13 +31,20 @@ public class BaseGoogleCloudStorageApiLiveTest extends BaseApiLiveTest<GoogleClo
protected static final String PROJECT_NUMBER = System.getProperty("test.google-cloud-storage.project-number");
public BaseGoogleCloudStorageApiLiveTest() {
protected BaseGoogleCloudStorageApiLiveTest() {
provider = "google-cloud-storage";
}
protected GoogleCloudStorageApi create(Properties props, Iterable<Module> modules) {
@Override protected ProviderMetadata createProviderMetadata(){
return new GoogleCloudStorageProviderMetadata();
}
@Override protected Properties setupProperties() {
return TestProperties.apply(provider, super.setupProperties());
}
@Override protected GoogleCloudStorageApi create(Properties props, Iterable<Module> modules) {
Injector injector = newBuilder().modules(modules).overrides(props).buildInjector();
return injector.getInstance(GoogleCloudStorageApi.class);
}
}

View File

@ -39,24 +39,22 @@ import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import javax.ws.rs.core.MediaType;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.crypto.Crypto;
import org.jclouds.googlecloudstorage.GoogleCloudStorageApiMetadata;
import org.jclouds.googlecloudstorage.GoogleCloudStorageProviderMetadata;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payload;
import org.jclouds.io.payloads.ByteSourcePayload;
import org.jclouds.oauth.v2.functions.BuildTokenRequest;
import org.jclouds.oauth.v2.functions.BuildTokenRequest.TestBuildTokenRequest;
import org.jclouds.providers.ProviderMetadata;
import org.jclouds.rest.internal.BaseRestApiExpectTest;
import org.jclouds.ssh.SshKeys;
import com.google.common.base.Joiner;
import com.google.common.base.Supplier;
@ -86,14 +84,11 @@ public class BaseGoogleCloudStorageExpectTest<T> extends BaseRestApiExpectTest<T
.payload(payloadFromString("{\n" + " \"access_token\" : \"" + TOKEN + "\",\n"
+ " \"token_type\" : \"Bearer\",\n" + " \"expires_in\" : 3600\n" + "}")).build();
protected String openSshKey;
public BaseGoogleCloudStorageExpectTest() {
protected BaseGoogleCloudStorageExpectTest() {
provider = "google-cloud-storage";
}
@Override
protected Module createModule() {
@Override protected Module createModule() {
return new Module() {
@Override
public void configure(Binder binder) {
@ -106,7 +101,6 @@ public class BaseGoogleCloudStorageExpectTest<T> extends BaseRestApiExpectTest<T
PublicKey publicKey = keyfactory
.generatePublic(publicKeySpec(ByteSource.wrap(PUBLIC_KEY.getBytes(UTF_8))));
KeyPair keyPair = new KeyPair(publicKey, privateKey);
openSshKey = SshKeys.encodeAsOpenSSH(RSAPublicKey.class.cast(publicKey));
final Crypto crypto = createMock(Crypto.class);
KeyPairGenerator rsaKeyPairGenerator = createMock(KeyPairGenerator.class);
final SecureRandom secureRandom = createMock(SecureRandom.class);
@ -137,16 +131,15 @@ public class BaseGoogleCloudStorageExpectTest<T> extends BaseRestApiExpectTest<T
};
}
@Override
protected Properties setupProperties() {
@Override protected Properties setupProperties() {
Properties props = super.setupProperties();
// use no sig algorithm for expect tests (means no credential is required either)
props.put(JWS_ALG, NONE);
return props;
}
@Override protected ApiMetadata createApiMetadata(){
return new GoogleCloudStorageApiMetadata();
@Override protected ProviderMetadata createProviderMetadata(){
return new GoogleCloudStorageProviderMetadata();
}
@Override

View File

@ -25,8 +25,7 @@ import com.google.inject.Injector;
public abstract class BaseGoogleCloudStorageParseTest<T> extends BaseItemParserTest<T> {
@Override
protected Injector injector() {
@Override protected Injector injector() {
return Guice.createInjector(new GsonModule(), new GoogleCloudStorageParserModule());
}
}

View File

@ -25,9 +25,9 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.googlecloudstorage.domain.Bucket;
import org.jclouds.googlecloudstorage.domain.Bucket.Cors;
import org.jclouds.googlecloudstorage.domain.BucketAccessControls;
import org.jclouds.googlecloudstorage.domain.BucketAccessControls.Role;
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.Location;
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.ObjectRole;
import org.jclouds.googlecloudstorage.domain.BucketAccessControls.Role;
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.StorageClass;
import org.jclouds.googlecloudstorage.domain.ObjectAccessControls;
import org.jclouds.googlecloudstorage.domain.Owner;

View File

@ -22,10 +22,11 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.googlecloud.domain.ForwardingListPage;
import org.jclouds.googlecloud.domain.ListPage;
import org.jclouds.googlecloudstorage.domain.Bucket;
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.Location;
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.StorageClass;
import org.jclouds.googlecloudstorage.domain.ListPage;
import org.jclouds.googlecloudstorage.domain.Owner;
import org.jclouds.googlecloudstorage.internal.BaseGoogleCloudStorageParseTest;
@ -55,6 +56,6 @@ public class NoAclBucketListTest extends BaseGoogleCloudStorageParseTest<ListPag
@Override @Consumes(MediaType.APPLICATION_JSON)
public ListPage<Bucket> expected() {
return ListPage.create(Arrays.asList(item1), "bhashbucket", null);
return ForwardingListPage.create(Arrays.asList(item1), "bhashbucket");
}
}

View File

@ -0,0 +1,83 @@
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<configuration scan="false">
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>target/test-data/jclouds.log</file>
<encoder>
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
</encoder>
</appender>
<appender name="WIREFILE" class="ch.qos.logback.core.FileAppender">
<file>target/test-data/jclouds-wire.log</file>
<encoder>
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
</encoder>
</appender>
<appender name="COMPUTEFILE" class="ch.qos.logback.core.FileAppender">
<file>target/test-data/jclouds-compute.log</file>
<encoder>
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
</encoder>
</appender>
<appender name="SSHFILE" class="ch.qos.logback.core.FileAppender">
<file>target/test-data/jclouds-ssh.log</file>
<encoder>
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
</encoder>
</appender>
<root>
<level value="warn" />
</root>
<logger name="org.jclouds">
<level value="TRACE" />
<appender-ref ref="FILE" />
</logger>
<logger name="jclouds.wire">
<level value="TRACE" />
<appender-ref ref="WIREFILE" />
</logger>
<logger name="jclouds.headers">
<level value="TRACE" />
<appender-ref ref="WIREFILE" />
</logger>
<logger name="jclouds.compute">
<level value="TRACE" />
<appender-ref ref="COMPUTEFILE" />
</logger>
<logger name="jclouds.ssh">
<level value="TRACE" />
<appender-ref ref="SSHFILE" />
</logger>
</configuration>