You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@jclouds.apache.org by Andrew Gaul <no...@github.com> on 2016/05/20 22:52:13 UTC

[jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

You can view, comment on, or merge this pull request online at:

  https://github.com/jclouds/jclouds-labs/pull/270

-- Commit Summary --

  * JCLOUDS-1005: Backblaze B2 skeleton and bucket ops

-- File Changes --

    A b2/pom.xml (162)
    A b2/src/main/java/org/jclouds/b2/B2ApiMetadata.java (85)
    A b2/src/main/java/org/jclouds/b2/B2Client.java (32)
    A b2/src/main/java/org/jclouds/b2/B2ResponseException.java (41)
    A b2/src/main/java/org/jclouds/b2/config/B2HttpApiModule.java (78)
    A b2/src/main/java/org/jclouds/b2/domain/Authorization.java (35)
    A b2/src/main/java/org/jclouds/b2/domain/B2Error.java (34)
    A b2/src/main/java/org/jclouds/b2/domain/Bucket.java (34)
    A b2/src/main/java/org/jclouds/b2/domain/BucketList.java (33)
    A b2/src/main/java/org/jclouds/b2/domain/BucketType.java (34)
    A b2/src/main/java/org/jclouds/b2/features/AuthorizationApi.java (54)
    A b2/src/main/java/org/jclouds/b2/features/BucketApi.java (87)
    A b2/src/main/java/org/jclouds/b2/filters/RequestAuthorization.java (91)
    A b2/src/main/java/org/jclouds/b2/handlers/ParseB2ErrorFromJsonContent.java (51)
    A b2/src/test/java/org/jclouds/b2/B2ApiMetadataTest.java (45)
    A b2/src/test/java/org/jclouds/b2/features/BucketApiLiveTest.java (96)
    A b2/src/test/java/org/jclouds/b2/features/BucketApiMockTest.java (239)
    A b2/src/test/java/org/jclouds/b2/internal/BaseB2ApiLiveTest.java (45)
    A b2/src/test/resources/authorize_account.json (7)
    A b2/src/test/resources/create_bucket.json (6)
    A b2/src/test/resources/create_bucket_request.json (5)
    A b2/src/test/resources/delete_bucket_request.json (4)
    A b2/src/test/resources/list_buckets.json (21)
    A b2/src/test/resources/list_buckets_request.json (3)
    A b2/src/test/resources/log4j.xml (106)
    A b2/src/test/resources/update_bucket_request.json (5)
    M pom.xml (1)

-- Patch Links --

https://github.com/jclouds/jclouds-labs/pull/270.patch
https://github.com/jclouds/jclouds-labs/pull/270.diff

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +import org.jclouds.rest.annotations.Headers;
> +import org.jclouds.rest.annotations.RequestFilters;
> +
> +import com.google.common.base.Charsets;
> +import com.google.common.io.BaseEncoding;
> +
> +public interface AuthorizationApi {
> +   @Named("b2_authorize_account")
> +   @GET
> +   @Path("/b2api/v1/b2_authorize_account")
> +   @Headers(keys = "Authorization", values = "{accountId}:{applicationKey}")
> +   @RequestFilters(Base64EncodeAuthorization.class)
> +   @Consumes(APPLICATION_JSON)
> +   Authorization authorizeAccount(@PathParam("accountId") String accountId, @PathParam("applicationKey") String applicationKey);
> +
> +   static final class Base64EncodeAuthorization implements HttpRequestFilter {

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64155923

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
@nacx Thanks for your feedback and help on this pull request!

---
You are receiving this because you modified the open/close state.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270#issuecomment-222328588

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
@nacx @zack-shoylev Could you review the skeleton for me?  B2 is the first provider I have written and I want to make sure it follows best practices.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270#issuecomment-220736968

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +import org.jclouds.labs.b2.domain.Authorization;
> +import org.jclouds.http.HttpException;
> +import org.jclouds.http.HttpRequest;
> +import org.jclouds.http.HttpRequestFilter;
> +import org.jclouds.rest.annotations.Headers;
> +import org.jclouds.rest.annotations.RequestFilters;
> +
> +import com.google.common.base.Charsets;
> +import com.google.common.io.BaseEncoding;
> +
> +public interface AuthorizationApi {
> +   @Named("b2_authorize_account")
> +   @GET
> +   @Path("/b2api/v1/b2_authorize_account")
> +   @Headers(keys = "Authorization", values = "{accountId}:{applicationKey}")
> +   @RequestFilters(Base64EncodeAuthorization.class)

Remove the `@Headers` annotation and use the existing filter: `@RequestFilter(BasicAuthentication.class)`.
Also, since the accountId is the "identity", you could create a class that extends the jclouds `MapBinder` (the one that binds the values tot he request the request) and has the Credentials injected. The mapbinder could then update the path with the identity, and you remove the need for the first "accountId" parameter.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64120158

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +    <jclouds.osgi.export>org.jclouds.b2*;version="${project.version}"</jclouds.osgi.export>
> +    <jclouds.osgi.import>org.jclouds*;version="${project.version}",*</jclouds.osgi.import>
> +  </properties>
> +
> +  <repositories>
> +    <repository>
> +      <id>apache-snapshots</id>
> +      <url>https://repository.apache.org/content/repositories/snapshots</url>
> +      <releases>
> +        <enabled>false</enabled>
> +      </releases>
> +      <snapshots>
> +        <enabled>true</enabled>
> +      </snapshots>
> +    </repository>
> +  </repositories>

This is already defined in the parent pom

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64484445

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +import org.jclouds.rest.annotations.Headers;
> +import org.jclouds.rest.annotations.RequestFilters;
> +
> +import com.google.common.base.Charsets;
> +import com.google.common.io.BaseEncoding;
> +
> +public interface AuthorizationApi {
> +   @Named("b2_authorize_account")
> +   @GET
> +   @Path("/b2api/v1/b2_authorize_account")
> +   @Headers(keys = "Authorization", values = "{accountId}:{applicationKey}")
> +   @RequestFilters(Base64EncodeAuthorization.class)
> +   @Consumes(APPLICATION_JSON)
> +   Authorization authorizeAccount(@PathParam("accountId") String accountId, @PathParam("applicationKey") String applicationKey);
> +
> +   static final class Base64EncodeAuthorization implements HttpRequestFilter {

This class is not needed; jclouds already provides it.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64120170

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> + * 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.labs.b2;
> +
> +import java.io.Closeable;
> +
> +import org.jclouds.labs.b2.features.AuthorizationApi;
> +import org.jclouds.labs.b2.features.BucketApi;
> +import org.jclouds.rest.annotations.Delegate;
> +
> +/** Provides access to Backblaze B2 resources via their REST API. */
> +public interface B2Client extends Closeable {

Convention is to name B2Api

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64119925

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +
> +import org.jclouds.http.HttpCommand;
> +import org.jclouds.http.HttpErrorHandler;
> +import org.jclouds.http.HttpResponse;
> +import org.jclouds.http.functions.ParseJson;
> +import org.jclouds.json.Json;
> +import org.jclouds.labs.b2.B2ResponseException;
> +import org.jclouds.labs.b2.domain.B2Error;
> +
> +import com.google.inject.Inject;
> +import com.google.inject.TypeLiteral;
> +
> +public class ParseB2ErrorFromJsonContent extends ParseJson<B2Error> implements HttpErrorHandler {
> +
> +   @Inject
> +   public ParseB2ErrorFromJsonContent(Json json) {

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64489803

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
Only a couple comments, but good to merge for me! This is looking great!

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270#issuecomment-222095917

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +import org.jclouds.http.HttpUtils;
> +import org.jclouds.labs.b2.B2Api;
> +import org.jclouds.labs.b2.domain.Authorization;
> +import org.jclouds.location.Provider;
> +import org.jclouds.logging.Logger;
> +
> +import com.google.common.base.Function;
> +import com.google.common.base.Supplier;
> +import com.google.common.cache.CacheBuilder;
> +import com.google.common.cache.CacheLoader;
> +import com.google.common.cache.LoadingCache;
> +
> +@Singleton
> +public class RequestAuthorization implements HttpRequestFilter {
> +   @Resource
> +   @Named(Constants.LOGGER_SIGNATURE)

I'm not sure about this logger, s this is not signing anything. Create a custom logger for b2?

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64485689

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +    <version>2.0.0-SNAPSHOT</version>
> +  </parent>
> +
> +  <!-- TODO: when out of labs, switch to org.jclouds.api -->
> +  <groupId>org.apache.jclouds.labs</groupId>
> +  <artifactId>b2</artifactId>
> +  <name>Apache jclouds B2 API</name>
> +  <description>BlobStore binding to the Backblaze B2 API</description>
> +  <packaging>bundle</packaging>
> +
> +  <properties>
> +    <test.aws.identity>FIXME_IDENTITY</test.aws.identity>
> +    <test.aws.credential>FIXME_CREDENTIAL</test.aws.credential>
> +    <test.b2.build-version />
> +    <test.b2.identity>${test.aws.identity}</test.b2.identity>
> +    <test.b2.credential>${test.aws.credential}</test.b2.credential>

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64155717

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> + */
> +package org.jclouds.labs.b2.domain;
> +
> +import java.util.List;
> +
> +import org.jclouds.json.SerializedNames;
> +
> +import com.google.auto.value.AutoValue;
> +
> +@AutoValue
> +public abstract class BucketList {
> +   public abstract List<Bucket> buckets();
> +
> +   @SerializedNames({"buckets"})
> +   public static BucketList create(List<Bucket> buckets) {
> +      return new AutoValue_BucketList(buckets);

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64489547

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> + * 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.labs.b2;
> +
> +import java.io.Closeable;
> +
> +import org.jclouds.labs.b2.features.AuthorizationApi;
> +import org.jclouds.labs.b2.features.BucketApi;
> +import org.jclouds.rest.annotations.Delegate;
> +
> +/** Provides access to Backblaze B2 resources via their REST API. */
> +public interface B2Client extends Closeable {

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64155704

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +
> +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.labs.b2.config.B2HttpApiModule;
> +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)
> +// TODO: B2ProviderMetadata?

Yes. The api metadata should just describe the API, and the provider metadata should add to the API the real endpoint (apis can provide a default one), and the default configuration. For providers that have their own API this makes less sense, but I think it is still good to separate both. HAve a look at the digitalocean2 provider for an example.

You may also want to use the same provider id for the api and provider, so just remove this annotation once the provider metadata exists, to avoid having conflicts.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64119825

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +   @RequestFilters(ReplacePayloadAccountId.class)
> +   @Consumes(APPLICATION_JSON)
> +   Bucket updateBucket(@PayloadParam("bucketId") String bucketId, @PayloadParam("bucketType") BucketType bucketType);
> +
> +   @Named("b2_list_buckets")
> +   @POST
> +   @Path("/b2api/v1/b2_list_buckets")
> +   @Payload("{\"accountId\":\"{accountId}\"}")
> +   @RequestFilters(ReplacePayloadAccountId.class)
> +   @Consumes(APPLICATION_JSON)
> +   BucketList listBuckets();
> +
> +   static final class ReplacePayloadAccountId implements HttpRequestFilter {
> +      @Override
> +      public HttpRequest filter(HttpRequest request) throws HttpException {
> +         String accountId = request.getFirstHeaderOrNull("accountId");  // TODO: hack

See below.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64118384

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +import org.jclouds.rest.annotations.MapBinder;
> +import org.jclouds.rest.annotations.PayloadParam;
> +import org.jclouds.rest.annotations.PayloadParams;
> +import org.jclouds.rest.annotations.RequestFilters;
> +import org.jclouds.rest.binders.BindToJsonPayload;
> +
> +@RequestFilters(RequestAuthorization.class)
> +@BlobScope(CONTAINER)
> +public interface BucketApi {
> +   @Named("b2_create_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_create_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)

[minor] Since all methods produce and consume the same, you can move this annotations to class level and remove them from each method.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/03ae2f5286f0feaaa7f66a03e3b037897a95d668#r64635758

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +               @Override
> +               public Authorization apply(Credentials creds) {
> +                  return b2Api.getAuthorizationApi().authorizeAccount();
> +               }
> +            }));
> +   }
> +
> +   @Override
> +   public HttpRequest filter(HttpRequest request) throws HttpException {
> +      utils.logRequest(signatureLog, request, ">>");
> +      Credentials creds = this.creds.get();
> +      Authorization auth = cache.getUnchecked(creds);
> +
> +      // Replace fixed URL with API URL, except for unit tests tests
> +      URI endpoint = request.getEndpoint();
> +      if (!endpoint.getHost().equals("localhost")) {

Can we get rid of this, which couples the code to the tests? Can we configure the tests, and the json returned by the authorization requests to return an api url that can make the tests work without this conditional?

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64488142

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +   @Named("b2_create_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_create_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)
> +   Bucket createBucket(@PayloadParam("bucketName") String bucketName, @PayloadParam("bucketType") BucketType bucketType);
> +
> +   @Named("b2_delete_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_delete_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)

I added `testDeleteAlreadyDeletedBucket` to test this.  B2 return 400 with a `bad_bucket_id`.  I modified `ParseB2ErrorFromJsonContent` to turn this into `ContainerNotFoundException`.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64495966

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
I addressed all outstanding review comments.  Tests will succeed after the next Maven snapshot update.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270#issuecomment-221167693

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +import com.google.common.cache.CacheBuilder;
> +import com.google.common.cache.CacheLoader;
> +import com.google.common.cache.LoadingCache;
> +
> +@Singleton
> +public class RequestAuthorization implements HttpRequestFilter {
> +   @Resource
> +   @Named(Constants.LOGGER_SIGNATURE)
> +   Logger signatureLog = Logger.NULL;
> +
> +   private final Supplier<Credentials> creds;
> +   private final HttpUtils utils;
> +   private final LoadingCache<Credentials, Authorization> cache;
> +
> +   @Inject
> +   public RequestAuthorization(@Provider Supplier<Credentials> creds, final B2Api b2Api, HttpUtils utils) {

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64489654

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +import com.google.common.cache.CacheBuilder;
> +import com.google.common.cache.CacheLoader;
> +import com.google.common.cache.LoadingCache;
> +
> +@Singleton
> +public class RequestAuthorization implements HttpRequestFilter {
> +   @Resource
> +   @Named(Constants.LOGGER_SIGNATURE)
> +   Logger signatureLog = Logger.NULL;
> +
> +   private final Supplier<Credentials> creds;
> +   private final HttpUtils utils;
> +   private final LoadingCache<Credentials, Authorization> cache;
> +
> +   @Inject
> +   public RequestAuthorization(@Provider Supplier<Credentials> creds, final B2Api b2Api, HttpUtils utils) {

As per Guice best practices, make this package-private by removing the modifier. 

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64487224

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +         requestJson = parser.parse(new String(request.getBody(), Charsets.UTF_8));
> +      } catch (Exception e) {
> +         throw Throwables.propagate(e);
> +      }
> +      JsonElement resourceJson = parser.parse(stringFromResource(resourceLocation));
> +      assertThat(requestJson).isEqualTo(resourceJson);
> +   }
> +
> +   /**
> +    * Ensures the request has a json header.
> +    *
> +    * @param request
> +    * @see RecordedRequest
> +    */
> +   private void assertContentTypeIsJSON(RecordedRequest request) {
> +      // TODO: where to add this?  something is stripping it off

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64292620

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
@andrewgaul I've commented about some structural things. Hope the hints help :) I'll go through the entire PR during the weekend!

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270#issuecomment-220741678

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
Just a couple final minor comments. LGTM!

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270#issuecomment-221682614

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +      super(builder);
> +   }
> +
> +   public static Properties defaultProperties() {
> +      Properties properties = BaseHttpApiMetadata.defaultProperties();
> +      return properties;
> +   }
> +
> +   public static class Builder extends BaseHttpApiMetadata.Builder<B2Api, Builder> {
> +
> +      protected Builder() {
> +         super(B2Api.class);
> +         id("b2")
> +                 .name("Backblaze B2 API")
> +                 .identityName("Access Key ID")
> +                 .credentialName("Secret Access Key")

In their naming, these are the "Account Id" and "Application Key"

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64484803

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +import org.jclouds.labs.b2.domain.B2Error;
> +
> +import com.google.inject.Inject;
> +import com.google.inject.TypeLiteral;
> +
> +public class ParseB2ErrorFromJsonContent extends ParseJson<B2Error> implements HttpErrorHandler {
> +
> +   @Inject
> +   public ParseB2ErrorFromJsonContent(Json json) {
> +      super(json, TypeLiteral.get(B2Error.class));
> +   }
> +
> +   private static Exception refineException(B2Error error, Exception exception) {
> +      if ("bad_json".equals(error.code())) {
> +         return new IllegalArgumentException(error.message(), exception);
> +      } else {

Also try to refine 404 errors to a ResourceNotFoundException to let the 404 fallbacks work

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64487543

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +import org.jclouds.labs.b2.domain.Authorization;
> +import org.jclouds.http.HttpException;
> +import org.jclouds.http.HttpRequest;
> +import org.jclouds.http.HttpRequestFilter;
> +import org.jclouds.rest.annotations.Headers;
> +import org.jclouds.rest.annotations.RequestFilters;
> +
> +import com.google.common.base.Charsets;
> +import com.google.common.io.BaseEncoding;
> +
> +public interface AuthorizationApi {
> +   @Named("b2_authorize_account")
> +   @GET
> +   @Path("/b2api/v1/b2_authorize_account")
> +   @Headers(keys = "Authorization", values = "{accountId}:{applicationKey}")
> +   @RequestFilters(Base64EncodeAuthorization.class)

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64328232

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +import static com.google.common.base.Preconditions.checkNotNull;
> +
> +import org.jclouds.labs.b2.domain.B2Error;
> +import org.jclouds.http.HttpCommand;
> +import org.jclouds.http.HttpResponse;
> +import org.jclouds.http.HttpResponseException;
> +
> +public class B2ResponseException extends HttpResponseException {
> +
> +   private static final long serialVersionUID = 1L;
> +   private final B2Error error;
> +
> +   public B2ResponseException(HttpCommand command, HttpResponse response, B2Error error) {
> +      super("request " + command.getCurrentRequest().getRequestLine() + " failed with code " + response.getStatusCode()
> +            + ", error: " + error.toString(), command, response);
> +      this.error = checkNotNull(error, "error");

This check should be performed *before* calling its toString() method.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64484949

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +  <parent>
> +    <groupId>org.apache.jclouds.labs</groupId>
> +    <artifactId>jclouds-labs</artifactId>
> +    <version>2.0.0-SNAPSHOT</version>
> +  </parent>
> +
> +  <!-- TODO: when out of labs, switch to org.jclouds.api -->
> +  <groupId>org.apache.jclouds.labs</groupId>
> +  <artifactId>b2</artifactId>
> +  <name>Apache jclouds B2 API</name>
> +  <description>BlobStore binding to the Backblaze B2 API</description>
> +  <packaging>bundle</packaging>
> +
> +  <properties>
> +    <test.aws.identity>FIXME_IDENTITY</test.aws.identity>
> +    <test.aws.credential>FIXME_CREDENTIAL</test.aws.credential>

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64155716

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +public class BaseB2ApiLiveTest extends BaseApiLiveTest<B2Api> {
> +
> +   protected BaseB2ApiLiveTest() {
> +      provider = "b2";
> +   }
> +
> +   @Override
> +   protected ApiMetadata createApiMetadata() {
> +      return new B2ApiMetadata();
> +   }
> +
> +   @Override
> +   protected B2Api create(Properties props, Iterable<Module> modules) {
> +      Injector injector = newBuilder().modules(modules).overrides(props).buildInjector();
> +      return injector.getInstance(B2Api.class);
> +   }

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64490032

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
Failures due to jclouds/jclouds#959.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270#issuecomment-220738629

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +    <jclouds.osgi.export>org.jclouds.b2*;version="${project.version}"</jclouds.osgi.export>
> +    <jclouds.osgi.import>org.jclouds*;version="${project.version}",*</jclouds.osgi.import>
> +  </properties>
> +
> +  <repositories>
> +    <repository>
> +      <id>apache-snapshots</id>
> +      <url>https://repository.apache.org/content/repositories/snapshots</url>
> +      <releases>
> +        <enabled>false</enabled>
> +      </releases>
> +      <snapshots>
> +        <enabled>true</enabled>
> +      </snapshots>
> +    </repository>
> +  </repositories>

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64489167

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +         assertThat(server.getRequestCount()).isEqualTo(2);
> +         assertAuthentication(server);
> +         assertRequest(server.takeRequest(), "POST", "/b2api/v1/b2_list_buckets", "/list_buckets_request.json");
> +      } finally {
> +         server.shutdown();
> +      }
> +   }
> +
> +   @SuppressWarnings("serial")
> +   public B2Api api(String uri, String provider, Properties overrides) {
> +      return ContextBuilder.newBuilder(provider)
> +            .credentials("ACCOUNT_ID", "APPLICATION_KEY")
> +            .endpoint(uri)
> +            .overrides(overrides)
> +            .modules(modules)
> +            .buildApi(new TypeToken<B2Api>(getClass()) {});

Just use `.buildApi(B2Api.class);`?

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64487840

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +import com.google.common.cache.LoadingCache;
> +
> +@Singleton
> +public class RequestAuthorization implements HttpRequestFilter {
> +   @Resource
> +   @Named(Constants.LOGGER_SIGNATURE)
> +   Logger signatureLog = Logger.NULL;
> +
> +   private final Supplier<Credentials> creds;
> +   private final HttpUtils utils;
> +   private final LoadingCache<Credentials, Authorization> cache;
> +
> +   @Inject
> +   public RequestAuthorization(@Provider Supplier<Credentials> creds, final B2Api b2Api, HttpUtils utils) {
> +      this.creds = checkNotNull(creds, "creds");
> +      this.utils = checkNotNull(utils, "utils");

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64489728

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +   @Named("b2_create_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_create_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)
> +   Bucket createBucket(@PayloadParam("bucketName") String bucketName, @PayloadParam("bucketType") BucketType bucketType);
> +
> +   @Named("b2_delete_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_delete_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)

Worth adding a `@Fallback(NullOnNotFoundOr404.class)`? It is a pretty common practice in jclouds to avoid failing if the resource one is trying to delete is already gone.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64485464

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +         assertThat(server.getRequestCount()).isEqualTo(2);
> +         assertAuthentication(server);
> +         assertRequest(server.takeRequest(), "POST", "/b2api/v1/b2_list_buckets", "/list_buckets_request.json");
> +      } finally {
> +         server.shutdown();
> +      }
> +   }
> +
> +   @SuppressWarnings("serial")
> +   public B2Api api(String uri, String provider, Properties overrides) {
> +      return ContextBuilder.newBuilder(provider)
> +            .credentials("ACCOUNT_ID", "APPLICATION_KEY")
> +            .endpoint(uri)
> +            .overrides(overrides)
> +            .modules(modules)
> +            .buildApi(new TypeToken<B2Api>(getClass()) {});

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64489913

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +
> +   @Override
> +   public HttpRequest filter(HttpRequest request) throws HttpException {
> +      utils.logRequest(signatureLog, request, ">>");
> +      Credentials creds = this.creds.get();
> +      Authorization auth = cache.getUnchecked(creds);
> +
> +      // Replace fixed URL with API URL, except for unit tests tests
> +      URI endpoint = request.getEndpoint();
> +      if (!endpoint.getHost().equals("localhost")) {
> +         endpoint = URI.create(auth.apiUrl() + endpoint.getPath() + (endpoint.getQuery() == null ? "" : "?" + endpoint.getQuery()));
> +      }
> +
> +      request = request.toBuilder()
> +            .endpoint(endpoint)
> +            // TODO: squirrel away accountId in bogus header so ReplacePayloadAccountId can use it

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64291999

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +   @Named("b2_create_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_create_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)
> +   Bucket createBucket(@PayloadParam("bucketName") String bucketName, @PayloadParam("bucketType") BucketType bucketType);
> +
> +   @Named("b2_delete_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_delete_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64782707

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +               @Override
> +               public Authorization apply(Credentials creds) {
> +                  return b2Api.getAuthorizationApi().authorizeAccount();
> +               }
> +            }));
> +   }
> +
> +   @Override
> +   public HttpRequest filter(HttpRequest request) throws HttpException {
> +      utils.logRequest(signatureLog, request, ">>");
> +      Credentials creds = this.creds.get();
> +      Authorization auth = cache.getUnchecked(creds);
> +
> +      // Replace fixed URL with API URL, except for unit tests tests
> +      URI endpoint = request.getEndpoint();
> +      if (!endpoint.getHost().equals("localhost")) {

I changed this but the alternative might not be better; we need to munge the port to get MockWebServer to work correctly.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64493687

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +      server.enqueue(new MockResponse().setBody(stringFromResource("/bucket.json")));
> +
> +      try {
> +         BucketApi api = api(server.getUrl("/").toString(), "b2").getBucketApi();
> +         Bucket response = api.deleteBucket("4a48fe8875c6214145260818");
> +         assertThat(response.bucketId()).isEqualTo("4a48fe8875c6214145260818");
> +         assertThat(response.bucketName()).isEqualTo("any_name_you_pick");
> +         assertThat(response.bucketType()).isEqualTo(BucketType.ALL_PRIVATE);
> +
> +         assertThat(server.getRequestCount()).isEqualTo(2);
> +         assertAuthentication(server);
> +         assertRequest(server.takeRequest(), "POST", "/b2api/v1/b2_delete_bucket", "/delete_bucket_request.json");
> +      } finally {
> +         server.shutdown();
> +      }
> +   }

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/2a136008e73694853e887a138883638321393bdd#r64993412

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +      server.enqueue(new MockResponse().setBody(stringFromResource("/bucket.json")));
> +
> +      try {
> +         BucketApi api = api(server.getUrl("/").toString(), "b2").getBucketApi();
> +         Bucket response = api.deleteBucket("4a48fe8875c6214145260818");
> +         assertThat(response.bucketId()).isEqualTo("4a48fe8875c6214145260818");
> +         assertThat(response.bucketName()).isEqualTo("any_name_you_pick");
> +         assertThat(response.bucketType()).isEqualTo(BucketType.ALL_PRIVATE);
> +
> +         assertThat(server.getRequestCount()).isEqualTo(2);
> +         assertAuthentication(server);
> +         assertRequest(server.takeRequest(), "POST", "/b2api/v1/b2_delete_bucket", "/delete_bucket_request.json");
> +      } finally {
> +         server.shutdown();
> +      }
> +   }

Add a test that exercises the fallback?

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/2a136008e73694853e887a138883638321393bdd#r64876192

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +      final Object fakeKey = new Object();  // fake key for single-element cache
> +      final LoadingCache<Object, Authorization> cache = CacheBuilder.newBuilder()
> +            .expireAfterWrite(23, TimeUnit.HOURS)
> +            .build(CacheLoader.from(new Function<Object, Authorization>() {
> +               @Override
> +               public Authorization apply(Object nothing) {
> +                  return b2Api.getAuthorizationApi().authorizeAccount();
> +               }
> +            }));
> +      return new Supplier<Authorization>() {
> +            @Override
> +            public Authorization get() {
> +               return cache.getUnchecked(fakeKey);
> +            }
> +         };
> +   }

A common practice in jclouds when you are providing a supplier on top of a cache and binding it to the Guice contex, is to use the jclouds memoized supplier. It already takes care of properly dealing with auth exceptions. It would be something like:
```java
@Provides
@Singleton
protected final Supplier<Authorization> provideAuthorizationSupplier(final B2Api b2Api) {
   return new Supplier<Authorization>() {
      @Override public Authorization get() {
         return b2Api.getAuthorizationApi().authorizeAccount();
      }
   };
}

@Provides
@Singleton
@Memoized
protected final Supplier<Authorization> provideAuthorizationCache(
      AtomicReference<AuthorizationException> authException,
      @Named(PROPERTY_SESSION_INTERVAL) long seconds,
      Supplier<Authorization>  uncached) {
   return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(
      authException, uncached, seconds, TimeUnit.SECONDS);
```

With this you can inject both suppliers. If you want to inject the cache, you just need to qualify the variable as `@Memoized`.

Also note that the `@Provides` methods are better marked final, as Guice 4 does not allow to override them. I've also used the `PROPERTY_SESSION_INTERVAL` property to configure the auth expiration. Feel free to consider if that makes sense in this provider. If it does, you could configure the 23 hours default value for that property in the api metadata.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/2a136008e73694853e887a138883638321393bdd#r64875953

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +
> +   @Override
> +   public HttpRequest filter(HttpRequest request) throws HttpException {
> +      utils.logRequest(signatureLog, request, ">>");
> +      Credentials creds = this.creds.get();
> +      Authorization auth = cache.getUnchecked(creds);
> +
> +      // Replace fixed URL with API URL, except for unit tests tests
> +      URI endpoint = request.getEndpoint();
> +      if (!endpoint.getHost().equals("localhost")) {
> +         endpoint = URI.create(auth.apiUrl() + endpoint.getPath() + (endpoint.getQuery() == null ? "" : "?" + endpoint.getQuery()));
> +      }
> +
> +      request = request.toBuilder()
> +            .endpoint(endpoint)
> +            // TODO: squirrel away accountId in bogus header so ReplacePayloadAccountId can use it

B2 requires the accountId in the JSON payload of requests but we don't want to include it in API calls.  Can I more cleanly pass this information to `ReplacePayloadAccountId`?

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64118365

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +               @Override
> +               public Authorization apply(Credentials creds) {
> +                  return b2Api.getAuthorizationApi().authorizeAccount();
> +               }
> +            }));
> +   }
> +
> +   @Override
> +   public HttpRequest filter(HttpRequest request) throws HttpException {
> +      utils.logRequest(signatureLog, request, ">>");
> +      Credentials creds = this.creds.get();
> +      Authorization auth = cache.getUnchecked(creds);
> +
> +      // Replace fixed URL with API URL, except for unit tests tests
> +      URI endpoint = request.getEndpoint();
> +      if (!endpoint.getHost().equals("localhost")) {

Re-reading this, I agree with you and will remove it.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64510699

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
Addressed all outstanding review comments.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270#issuecomment-222327435

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +public class BaseB2ApiLiveTest extends BaseApiLiveTest<B2Api> {
> +
> +   protected BaseB2ApiLiveTest() {
> +      provider = "b2";
> +   }
> +
> +   @Override
> +   protected ApiMetadata createApiMetadata() {
> +      return new B2ApiMetadata();
> +   }
> +
> +   @Override
> +   protected B2Api create(Properties props, Iterable<Module> modules) {
> +      Injector injector = newBuilder().modules(modules).overrides(props).buildInjector();
> +      return injector.getInstance(B2Api.class);
> +   }

Is there a real need to override this method? It looks like it does the same than the parent?

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64488024

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +
> +   @Override
> +   public HttpRequest filter(HttpRequest request) throws HttpException {
> +      utils.logRequest(signatureLog, request, ">>");
> +      Credentials creds = this.creds.get();
> +      Authorization auth = cache.getUnchecked(creds);
> +
> +      // Replace fixed URL with API URL, except for unit tests tests
> +      URI endpoint = request.getEndpoint();
> +      if (!endpoint.getHost().equals("localhost")) {
> +         endpoint = URI.create(auth.apiUrl() + endpoint.getPath() + (endpoint.getQuery() == null ? "" : "?" + endpoint.getQuery()));
> +      }
> +
> +      request = request.toBuilder()
> +            .endpoint(endpoint)
> +            // TODO: squirrel away accountId in bogus header so ReplacePayloadAccountId can use it

This suggestion will take me a little while to investigate.  I will push an amended commit addressing all other comments.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64156127

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +   @Named("b2_create_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_create_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)
> +   Bucket createBucket(@PayloadParam("bucketName") String bucketName, @PayloadParam("bucketType") BucketType bucketType);
> +
> +   @Named("b2_delete_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_delete_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)

Now that it turns it into that exception, adding the `@Fallback(NullOnNotFoundOr404.class)` would already work (as it looks for 404 errors or exceptions that are instanceof ResoueceNotFoundException).
With that fallback method would return just `null` if the object didn't already exist instead of throwing an exception, which is a pretty common pattern in most of the jclouds APIs. Worth adding the fallback? 

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64637406

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +
> +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.labs.b2.config.B2HttpApiModule;
> +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)
> +// TODO: B2ProviderMetadata?

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64156115

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
Addressed all outstanding review comments.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270#issuecomment-221932992

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +
> +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.labs.b2.config.B2HttpApiModule;
> +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)
> +// TODO: B2ProviderMetadata?

Is the difference between API and provider meaningful?

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64118241

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +   @Named("b2_create_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_create_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)
> +   Bucket createBucket(@PayloadParam("bucketName") String bucketName, @PayloadParam("bucketType") BucketType bucketType);
> +
> +   @Named("b2_delete_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_delete_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)

Yes, it does not return a 404, but it actually throws a ResourceNotFoundException when the referenced bucket is not found (which in practice, for jclouds is just the same as if it had returned a 404).

What I mean, is that a common practice in jclouds is to avoid failing on delete operations if the resource to be deleted does not exist. [The S3 API](https://github.com/jclouds/jclouds/blob/master/apis/s3/src/main/java/org/jclouds/s3/S3Client.java#L207) and many others behave this way, and I think it would be good to follow that pattern here too.

If you annotate this method with `@Fallback(NullOnNotFoundOr404.class)`, then the method will not fail and just return `null` when the resource to be deleted does not exist, just like most of the other jclouds APIs. The fallback will not only take place if the response is a 404, [but also if the call generated a ResoueceNotFoundException](https://github.com/jclouds/jclouds/blob/master/core/src/main/java/org/jclouds/Fallbacks.java#L138-L140). Don't be "distracted" by the "Or404" in the fallback name; it checks for exceptions too, and your error handler already takes care of properly setting it when appropriate, so APIs can use this kind of callbacks.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64715048

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +import com.google.common.cache.LoadingCache;
> +
> +@Singleton
> +public class RequestAuthorization implements HttpRequestFilter {
> +   @Resource
> +   @Named(Constants.LOGGER_SIGNATURE)
> +   Logger signatureLog = Logger.NULL;
> +
> +   private final Supplier<Credentials> creds;
> +   private final HttpUtils utils;
> +   private final LoadingCache<Credentials, Authorization> cache;
> +
> +   @Inject
> +   public RequestAuthorization(@Provider Supplier<Credentials> creds, final B2Api b2Api, HttpUtils utils) {
> +      this.creds = checkNotNull(creds, "creds");
> +      this.utils = checkNotNull(utils, "utils");

Checks are redundant. The injector already enforces non-null values.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64487262

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +   @RequestFilters(ReplacePayloadAccountId.class)
> +   @Consumes(APPLICATION_JSON)
> +   Bucket updateBucket(@PayloadParam("bucketId") String bucketId, @PayloadParam("bucketType") BucketType bucketType);
> +
> +   @Named("b2_list_buckets")
> +   @POST
> +   @Path("/b2api/v1/b2_list_buckets")
> +   @Payload("{\"accountId\":\"{accountId}\"}")
> +   @RequestFilters(ReplacePayloadAccountId.class)
> +   @Consumes(APPLICATION_JSON)
> +   BucketList listBuckets();
> +
> +   static final class ReplacePayloadAccountId implements HttpRequestFilter {
> +      @Override
> +      public HttpRequest filter(HttpRequest request) throws HttpException {
> +         String accountId = request.getFirstHeaderOrNull("accountId");  // TODO: hack

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64292638

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +import org.jclouds.labs.b2.domain.B2Error;
> +
> +import com.google.inject.Inject;
> +import com.google.inject.TypeLiteral;
> +
> +public class ParseB2ErrorFromJsonContent extends ParseJson<B2Error> implements HttpErrorHandler {
> +
> +   @Inject
> +   public ParseB2ErrorFromJsonContent(Json json) {
> +      super(json, TypeLiteral.get(B2Error.class));
> +   }
> +
> +   private static Exception refineException(B2Error error, Exception exception) {
> +      if ("bad_json".equals(error.code())) {
> +         return new IllegalArgumentException(error.message(), exception);
> +      } else {

Let's address this in the upcoming object pull request which will encounter 404 errors.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64493814

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +import static com.google.common.base.Preconditions.checkNotNull;
> +
> +import org.jclouds.labs.b2.domain.B2Error;
> +import org.jclouds.http.HttpCommand;
> +import org.jclouds.http.HttpResponse;
> +import org.jclouds.http.HttpResponseException;
> +
> +public class B2ResponseException extends HttpResponseException {
> +
> +   private static final long serialVersionUID = 1L;
> +   private final B2Error error;
> +
> +   public B2ResponseException(HttpCommand command, HttpResponse response, B2Error error) {
> +      super("request " + command.getCurrentRequest().getRequestLine() + " failed with code " + response.getStatusCode()
> +            + ", error: " + error.toString(), command, response);
> +      this.error = checkNotNull(error, "error");

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64489323

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +   @Named("b2_create_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_create_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)
> +   Bucket createBucket(@PayloadParam("bucketName") String bucketName, @PayloadParam("bucketType") BucketType bucketType);
> +
> +   @Named("b2_delete_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_delete_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)

Sorry I do not understand this comment.  B2 does not return 404:

https://www.backblaze.com/b2/docs/b2_delete_bucket.html

`ParseB2ErrorFromJsonContent` already maps `bad_bucket_id` to `ContainerNotFoundException` which `testDeleteAlreadyDeletedBucket` exercises so what else can we do here?

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64666211

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +      final Object fakeKey = new Object();  // fake key for single-element cache
> +      final LoadingCache<Object, Authorization> cache = CacheBuilder.newBuilder()
> +            .expireAfterWrite(23, TimeUnit.HOURS)
> +            .build(CacheLoader.from(new Function<Object, Authorization>() {
> +               @Override
> +               public Authorization apply(Object nothing) {
> +                  return b2Api.getAuthorizationApi().authorizeAccount();
> +               }
> +            }));
> +      return new Supplier<Authorization>() {
> +            @Override
> +            public Authorization get() {
> +               return cache.getUnchecked(fakeKey);
> +            }
> +         };
> +   }

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/2a136008e73694853e887a138883638321393bdd#r64993265

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +         requestJson = parser.parse(new String(request.getBody(), Charsets.UTF_8));
> +      } catch (Exception e) {
> +         throw Throwables.propagate(e);
> +      }
> +      JsonElement resourceJson = parser.parse(stringFromResource(resourceLocation));
> +      assertThat(requestJson).isEqualTo(resourceJson);
> +   }
> +
> +   /**
> +    * Ensures the request has a json header.
> +    *
> +    * @param request
> +    * @see RecordedRequest
> +    */
> +   private void assertContentTypeIsJSON(RecordedRequest request) {
> +      // TODO: where to add this?  something is stripping it off

Something strips off my Content-Type -- any idea how to force this?

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64118407

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +    <version>2.0.0-SNAPSHOT</version>
> +  </parent>
> +
> +  <!-- TODO: when out of labs, switch to org.jclouds.api -->
> +  <groupId>org.apache.jclouds.labs</groupId>
> +  <artifactId>b2</artifactId>
> +  <name>Apache jclouds B2 API</name>
> +  <description>BlobStore binding to the Backblaze B2 API</description>
> +  <packaging>bundle</packaging>
> +
> +  <properties>
> +    <test.aws.identity>FIXME_IDENTITY</test.aws.identity>
> +    <test.aws.credential>FIXME_CREDENTIAL</test.aws.credential>
> +    <test.b2.build-version />
> +    <test.b2.identity>${test.aws.identity}</test.b2.identity>
> +    <test.b2.credential>${test.aws.credential}</test.b2.credential>

Same here

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64119906

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> + */
> +package org.jclouds.labs.b2.domain;
> +
> +import java.util.List;
> +
> +import org.jclouds.json.SerializedNames;
> +
> +import com.google.auto.value.AutoValue;
> +
> +@AutoValue
> +public abstract class BucketList {
> +   public abstract List<Bucket> buckets();
> +
> +   @SerializedNames({"buckets"})
> +   public static BucketList create(List<Bucket> buckets) {
> +      return new AutoValue_BucketList(buckets);

Enforce an immutable list by using copyOf

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64485117

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +
> +   @Override
> +   public HttpRequest filter(HttpRequest request) throws HttpException {
> +      utils.logRequest(signatureLog, request, ">>");
> +      Credentials creds = this.creds.get();
> +      Authorization auth = cache.getUnchecked(creds);
> +
> +      // Replace fixed URL with API URL, except for unit tests tests
> +      URI endpoint = request.getEndpoint();
> +      if (!endpoint.getHost().equals("localhost")) {
> +         endpoint = URI.create(auth.apiUrl() + endpoint.getPath() + (endpoint.getQuery() == null ? "" : "?" + endpoint.getQuery()));
> +      }
> +
> +      request = request.toBuilder()
> +            .endpoint(endpoint)
> +            // TODO: squirrel away accountId in bogus header so ReplacePayloadAccountId can use it

With a minor modification in jclouds core: yes.

Change the `RestAnnotationProcessor` to have the Credentials injected. Then, add the following line after [these ones](https://github.com/jclouds/jclouds/blob/master/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java#L229-L230):
```java
tokenValues.put(Constants.PROPERTY_IDENTITY, credentials.identity);
```

With this change in place, you will be able to declare the methods like:
```java
@Named("b2_list_buckets")
@POST
@Path("/b2api/v1/b2_list_buckets")
@PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
@Consumes(APPLICATION_JSON)
BucketList listBuckets();
```
Removing the need for the filters and hacks, as jclouds will already substitute the identity in the parameter value.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64120564

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +
> +import org.jclouds.http.HttpCommand;
> +import org.jclouds.http.HttpErrorHandler;
> +import org.jclouds.http.HttpResponse;
> +import org.jclouds.http.functions.ParseJson;
> +import org.jclouds.json.Json;
> +import org.jclouds.labs.b2.B2ResponseException;
> +import org.jclouds.labs.b2.domain.B2Error;
> +
> +import com.google.inject.Inject;
> +import com.google.inject.TypeLiteral;
> +
> +public class ParseB2ErrorFromJsonContent extends ParseJson<B2Error> implements HttpErrorHandler {
> +
> +   @Inject
> +   public ParseB2ErrorFromJsonContent(Json json) {

Make this package private

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64487492

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +import org.jclouds.rest.annotations.MapBinder;
> +import org.jclouds.rest.annotations.PayloadParam;
> +import org.jclouds.rest.annotations.PayloadParams;
> +import org.jclouds.rest.annotations.RequestFilters;
> +import org.jclouds.rest.binders.BindToJsonPayload;
> +
> +@RequestFilters(RequestAuthorization.class)
> +@BlobScope(CONTAINER)
> +public interface BucketApi {
> +   @Named("b2_create_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_create_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/03ae2f5286f0feaaa7f66a03e3b037897a95d668#r64665027

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +  <parent>
> +    <groupId>org.apache.jclouds.labs</groupId>
> +    <artifactId>jclouds-labs</artifactId>
> +    <version>2.0.0-SNAPSHOT</version>
> +  </parent>
> +
> +  <!-- TODO: when out of labs, switch to org.jclouds.api -->
> +  <groupId>org.apache.jclouds.labs</groupId>
> +  <artifactId>b2</artifactId>
> +  <name>Apache jclouds B2 API</name>
> +  <description>BlobStore binding to the Backblaze B2 API</description>
> +  <packaging>bundle</packaging>
> +
> +  <properties>
> +    <test.aws.identity>FIXME_IDENTITY</test.aws.identity>
> +    <test.aws.credential>FIXME_CREDENTIAL</test.aws.credential>

aws? :)

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/08f67d68c03760ce134ccf217c3b1ee4487ac318#r64119894

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +import org.jclouds.http.HttpUtils;
> +import org.jclouds.labs.b2.B2Api;
> +import org.jclouds.labs.b2.domain.Authorization;
> +import org.jclouds.location.Provider;
> +import org.jclouds.logging.Logger;
> +
> +import com.google.common.base.Function;
> +import com.google.common.base.Supplier;
> +import com.google.common.cache.CacheBuilder;
> +import com.google.common.cache.CacheLoader;
> +import com.google.common.cache.LoadingCache;
> +
> +@Singleton
> +public class RequestAuthorization implements HttpRequestFilter {
> +   @Resource
> +   @Named(Constants.LOGGER_SIGNATURE)

I agree that B2 authorization is not strictly signing but as is it goes where all the other authentication logs go.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64496041

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +      super(builder);
> +   }
> +
> +   public static Properties defaultProperties() {
> +      Properties properties = BaseHttpApiMetadata.defaultProperties();
> +      return properties;
> +   }
> +
> +   public static class Builder extends BaseHttpApiMetadata.Builder<B2Api, Builder> {
> +
> +      protected Builder() {
> +         super(B2Api.class);
> +         id("b2")
> +                 .name("Backblaze B2 API")
> +                 .identityName("Access Key ID")
> +                 .credentialName("Secret Access Key")

Done.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64489265

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Andrew Gaul <no...@github.com>.
> +   @Override
> +   protected void configure() {
> +      super.configure();
> +      bind(RequestAuthorization.class).in(Scopes.SINGLETON);
> +   }
> +
> +   @Override
> +   protected void bindErrorHandlers() {
> +      bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseB2ErrorFromJsonContent.class);
> +      bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseB2ErrorFromJsonContent.class);
> +      bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseB2ErrorFromJsonContent.class);
> +   }
> +
> +   @Provides
> +   @Singleton
> +   static Supplier<Authorization> provideAuthorizationCache(final B2Api b2Api) {

I made some changes to the authorization cache to support upcoming commits.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/2a136008e73694853e887a138883638321393bdd#r64795475

Re: [jclouds/jclouds-labs] JCLOUDS-1005: Backblaze B2 skeleton and bucket ops (#270)

Posted by Ignasi Barrera <no...@github.com>.
> +   @Named("b2_create_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_create_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)
> +   Bucket createBucket(@PayloadParam("bucketName") String bucketName, @PayloadParam("bucketType") BucketType bucketType);
> +
> +   @Named("b2_delete_bucket")
> +   @POST
> +   @Path("/b2api/v1/b2_delete_bucket")
> +   @MapBinder(BindToJsonPayload.class)
> +   @PayloadParams(keys = {"accountId"}, values = {"{jclouds.identity}"})
> +   @Consumes(APPLICATION_JSON)
> +   @Produces(APPLICATION_JSON)

Hmm having a deeper look seems that this api never returns a 404?

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/270/files/8bb355e1b286b2bbf77fd8d3cb75cd2d1aa6bc69#r64485562