listAcls(BlobId blob);
+ /**
+ * Creates a new HMAC Key for the provided service account, including the secret key. Note that
+ * the secret key is only returned upon creation via this method.
+ *
+ * Example of creating a new HMAC Key.
+ *
+ *
{@code
+ * ServiceAccount serviceAccount = ServiceAccount.of("my-service-account@google.com");
+ *
+ * HmacKey hmacKey = storage.createHmacKey(serviceAccount);
+ *
+ * String secretKey = hmacKey.getSecretKey();
+ * HmacKey.HmacKeyMetadata metadata = hmacKey.getMetadata();
+ * }
+ *
+ * @throws StorageException upon failure
+ */
+ HmacKey createHmacKey(ServiceAccount serviceAccount, CreateHmacKeyOption... options);
+
+ /**
+ * Lists HMAC keys for a given service account. Note this returns {@code HmacKeyMetadata} objects,
+ * which do not contain secret keys.
+ *
+ * Example of listing HMAC keys, specifying project id.
+ *
+ *
{@code
+ * Page metadataPage = storage.listHmacKeys(
+ * Storage.ListHmacKeysOption.projectId("my-project-id"));
+ * for (HmacKey.HmacKeyMetadata hmacKeyMetadata : metadataPage.getValues()) {
+ * //do something with the metadata
+ * }
+ * }
+ *
+ * Example of listing HMAC keys, specifying max results and showDeletedKeys. Since projectId is
+ * not specified, the same project ID as the storage client instance will be used
+ *
+ *
{@code
+ * ServiceAccount serviceAccount = ServiceAccount.of("my-service-account@google.com");
+ *
+ * Page metadataPage = storage.listHmacKeys(
+ * Storage.ListHmacKeysOption.serviceAccount(serviceAccount),
+ * Storage.ListHmacKeysOption.maxResults(10L),
+ * Storage.ListHmacKeysOption.showDeletedKeys(true));
+ * for (HmacKey.HmacKeyMetadata hmacKeyMetadata : metadataPage.getValues()) {
+ * //do something with the metadata
+ * }
+ * }
+ *
+ * @param options the options to apply to this operation
+ * @throws StorageException upon failure
+ */
+ Page listHmacKeys(ListHmacKeysOption... options);
+
+ /**
+ * Gets an HMAC key given its access id. Note that this returns a {@code HmacKeyMetadata} object,
+ * which does not contain the secret key.
+ *
+ * Example of getting an HMAC key. Since projectId isn't specified, the same project ID as the
+ * storage client instance will be used.
+ *
+ *
{@code
+ * String hmacKeyAccessId = "my-access-id";
+ * HmacKey.HmackeyMetadata hmacKeyMetadata = storage.getHmacKey(hmacKeyAccessId);
+ * }
+ *
+ * @throws StorageException upon failure
+ */
+ HmacKeyMetadata getHmacKey(String accessId, GetHmacKeyOption... options);
+
+ /**
+ * Deletes an HMAC key. Note that only an {@code INACTIVE} key can be deleted. Attempting to
+ * delete a key whose {@code HmacKey.HmacKeyState} is anything other than {@code INACTIVE} will
+ * fail.
+ *
+ * Example of updating an HMAC key's state to INACTIVE and then deleting it.
+ *
+ *
{@code
+ * String hmacKeyAccessId = "my-access-id";
+ * HmacKey.HmacKeyMetadata hmacKeyMetadata = storage.getHmacKey(hmacKeyAccessId);
+ *
+ * storage.updateHmacKeyState(hmacKeyMetadata, HmacKey.HmacKeyState.INACTIVE);
+ * storage.deleteHmacKey(hmacKeyMetadata);
+ * }
+ *
+ * @throws StorageException upon failure
+ */
+ void deleteHmacKey(HmacKeyMetadata hmacKeyMetadata, DeleteHmacKeyOption... options);
+
+ /**
+ * Updates the state of an HMAC key and returns the updated metadata.
+ *
+ * Example of updating the state of an HMAC key.
+ *
+ *
{@code
+ * String hmacKeyAccessId = "my-access-id";
+ * HmacKey.HmacKeyMetadata hmacKeyMetadata = storage.getHmacKey(hmacKeyAccessId);
+ *
+ * storage.updateHmacKeyState(hmacKeyMetadata, HmacKey.HmacKeyState.INACTIVE);
+ * }
+ *
+ * @throws StorageException upon failure
+ */
+ HmacKeyMetadata updateHmacKeyState(
+ final HmacKeyMetadata hmacKeyMetadata,
+ final HmacKey.HmacKeyState state,
+ UpdateHmacKeyOption... options);
/**
* Gets the IAM policy for the provided bucket.
*
diff --git a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java
index 6f127ac5fb0c..33eab5dfd9ab 100644
--- a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java
+++ b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java
@@ -48,6 +48,7 @@
import com.google.cloud.RetryHelper.RetryHelperException;
import com.google.cloud.Tuple;
import com.google.cloud.storage.Acl.Entity;
+import com.google.cloud.storage.HmacKey.HmacKeyMetadata;
import com.google.cloud.storage.spi.v1.StorageRpc;
import com.google.cloud.storage.spi.v1.StorageRpc.RewriteResponse;
import com.google.common.base.Function;
@@ -297,6 +298,23 @@ public Page getNextPage() {
}
}
+ private static class HmacKeyMetadataPageFetcher implements NextPageFetcher {
+
+ private static final long serialVersionUID = 308012320541700881L;
+ private final StorageOptions serviceOptions;
+ private final Map options;
+
+ HmacKeyMetadataPageFetcher(StorageOptions serviceOptions, Map options) {
+ this.serviceOptions = serviceOptions;
+ this.options = options;
+ }
+
+ @Override
+ public Page getNextPage() {
+ return listHmacKeys(serviceOptions, options);
+ }
+ }
+
@Override
public Page list(BucketListOption... options) {
return listBuckets(getOptions(), optionMap(options));
@@ -1163,6 +1181,140 @@ public List call() {
}
}
+ public HmacKey createHmacKey(
+ final ServiceAccount serviceAccount, final CreateHmacKeyOption... options) {
+ try {
+ return HmacKey.fromPb(
+ runWithRetries(
+ new Callable() {
+ @Override
+ public com.google.api.services.storage.model.HmacKey call() {
+ return storageRpc.createHmacKey(serviceAccount.getEmail(), optionMap(options));
+ }
+ },
+ getOptions().getRetrySettings(),
+ EXCEPTION_HANDLER,
+ getOptions().getClock()));
+ } catch (RetryHelperException e) {
+ throw StorageException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public Page listHmacKeys(ListHmacKeysOption... options) {
+ return listHmacKeys(getOptions(), optionMap(options));
+ }
+
+ @Override
+ public HmacKeyMetadata getHmacKey(final String accessId, final GetHmacKeyOption... options) {
+ try {
+ return HmacKeyMetadata.fromPb(
+ runWithRetries(
+ new Callable() {
+ @Override
+ public com.google.api.services.storage.model.HmacKeyMetadata call() {
+ return storageRpc.getHmacKey(accessId, optionMap(options));
+ }
+ },
+ getOptions().getRetrySettings(),
+ EXCEPTION_HANDLER,
+ getOptions().getClock()));
+ } catch (RetryHelperException e) {
+ throw StorageException.translateAndThrow(e);
+ }
+ }
+
+ private HmacKeyMetadata updateHmacKey(
+ final HmacKeyMetadata hmacKeyMetadata, final UpdateHmacKeyOption... options) {
+ try {
+ return HmacKeyMetadata.fromPb(
+ runWithRetries(
+ new Callable() {
+ @Override
+ public com.google.api.services.storage.model.HmacKeyMetadata call() {
+ return storageRpc.updateHmacKey(hmacKeyMetadata.toPb(), optionMap(options));
+ }
+ },
+ getOptions().getRetrySettings(),
+ EXCEPTION_HANDLER,
+ getOptions().getClock()));
+ } catch (RetryHelperException e) {
+ throw StorageException.translateAndThrow(e);
+ }
+ }
+
+ @Override
+ public HmacKeyMetadata updateHmacKeyState(
+ final HmacKeyMetadata hmacKeyMetadata,
+ final HmacKey.HmacKeyState state,
+ final UpdateHmacKeyOption... options) {
+ HmacKeyMetadata updatedMetadata =
+ HmacKeyMetadata.newBuilder(hmacKeyMetadata.getServiceAccount())
+ .setProjectId(hmacKeyMetadata.getProjectId())
+ .setAccessId(hmacKeyMetadata.getAccessId())
+ .setState(state)
+ .build();
+ return updateHmacKey(updatedMetadata, options);
+ }
+
+ @Override
+ public void deleteHmacKey(final HmacKeyMetadata metadata, final DeleteHmacKeyOption... options) {
+ try {
+ runWithRetries(
+ new Callable() {
+ @Override
+ public Void call() {
+ storageRpc.deleteHmacKey(metadata.toPb(), optionMap(options));
+ return null;
+ }
+ },
+ getOptions().getRetrySettings(),
+ EXCEPTION_HANDLER,
+ getOptions().getClock());
+ } catch (RetryHelperException e) {
+ throw StorageException.translateAndThrow(e);
+ }
+ }
+
+ private static Page listHmacKeys(
+ final StorageOptions serviceOptions, final Map options) {
+ try {
+ Tuple> result =
+ runWithRetries(
+ new Callable<
+ Tuple<
+ String, Iterable>>() {
+ @Override
+ public Tuple<
+ String, Iterable>
+ call() {
+ return serviceOptions.getStorageRpcV1().listHmacKeys(options);
+ }
+ },
+ serviceOptions.getRetrySettings(),
+ EXCEPTION_HANDLER,
+ serviceOptions.getClock());
+ String cursor = result.x();
+ final Iterable metadata =
+ result.y() == null
+ ? ImmutableList.of()
+ : Iterables.transform(
+ result.y(),
+ new Function<
+ com.google.api.services.storage.model.HmacKeyMetadata, HmacKeyMetadata>() {
+ @Override
+ public HmacKeyMetadata apply(
+ com.google.api.services.storage.model.HmacKeyMetadata metadataPb) {
+ return HmacKeyMetadata.fromPb(metadataPb);
+ }
+ });
+ return new PageImpl<>(
+ new HmacKeyMetadataPageFetcher(serviceOptions, options), cursor, metadata);
+ } catch (RetryHelperException e) {
+ throw StorageException.translateAndThrow(e);
+ }
+ }
+
@Override
public Policy getIamPolicy(final String bucket, BucketSourceOption... options) {
try {
diff --git a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/HttpStorageRpc.java b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/HttpStorageRpc.java
index d162b33c5c7f..847bb3374ec4 100644
--- a/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/HttpStorageRpc.java
+++ b/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/HttpStorageRpc.java
@@ -46,6 +46,9 @@
import com.google.api.services.storage.model.Buckets;
import com.google.api.services.storage.model.ComposeRequest;
import com.google.api.services.storage.model.ComposeRequest.SourceObjects.ObjectPreconditions;
+import com.google.api.services.storage.model.HmacKey;
+import com.google.api.services.storage.model.HmacKeyMetadata;
+import com.google.api.services.storage.model.HmacKeysMetadata;
import com.google.api.services.storage.model.Notification;
import com.google.api.services.storage.model.ObjectAccessControl;
import com.google.api.services.storage.model.Objects;
@@ -1231,6 +1234,132 @@ public List listAcls(String bucket, String object, Long gen
}
}
+ @Override
+ public HmacKey createHmacKey(String serviceAccountEmail, Map