All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.azure.security.keyvault.administration.KeyVaultBackupAsyncClient Maven / Gradle / Ivy

There is a newer version: 4.6.0
Show newest version
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.security.keyvault.administration;

import com.azure.core.annotation.ReturnType;
import com.azure.core.annotation.ServiceClient;
import com.azure.core.annotation.ServiceMethod;
import com.azure.core.exception.HttpResponseException;
import com.azure.core.http.HttpPipeline;
import com.azure.core.http.rest.Response;
import com.azure.core.http.rest.SimpleResponse;
import com.azure.core.util.Context;
import com.azure.core.util.logging.ClientLogger;
import com.azure.core.util.polling.LongRunningOperationStatus;
import com.azure.core.util.polling.PollResponse;
import com.azure.core.util.polling.PollerFlux;
import com.azure.core.util.polling.PollingContext;
import com.azure.security.keyvault.administration.implementation.KeyVaultBackupClientImpl;
import com.azure.security.keyvault.administration.implementation.KeyVaultErrorCodeStrings;
import com.azure.security.keyvault.administration.implementation.models.RestoreOperation;
import com.azure.security.keyvault.administration.implementation.models.RestoreOperationParameters;
import com.azure.security.keyvault.administration.implementation.models.SASTokenParameter;
import com.azure.security.keyvault.administration.implementation.models.SelectiveKeyRestoreOperationParameters;
import com.azure.security.keyvault.administration.models.KeyVaultAdministrationException;
import com.azure.security.keyvault.administration.models.KeyVaultBackupOperation;
import com.azure.security.keyvault.administration.models.KeyVaultLongRunningOperation;
import com.azure.security.keyvault.administration.models.KeyVaultRestoreOperation;
import com.azure.security.keyvault.administration.models.KeyVaultRestoreResult;
import com.azure.security.keyvault.administration.models.KeyVaultSelectiveKeyRestoreOperation;
import com.azure.security.keyvault.administration.models.KeyVaultSelectiveKeyRestoreResult;
import reactor.core.publisher.Mono;

import java.net.URL;
import java.time.Duration;
import java.util.Locale;
import java.util.Objects;
import java.util.function.Function;

import static com.azure.core.util.FluxUtil.monoError;
import static com.azure.core.util.FluxUtil.withContext;
import static com.azure.security.keyvault.administration.KeyVaultAdministrationUtil.toLongRunningOperationStatus;
import static com.azure.security.keyvault.administration.KeyVaultAdministrationUtil.transformToLongRunningOperation;
import static com.azure.security.keyvault.administration.implementation.KeyVaultAdministrationUtils.createKeyVaultErrorFromError;

/**
 * The {@link KeyVaultBackupAsyncClient} provides asynchronous methods to perform full a backup and restore of a key
 * vault, as well as selectively restoring specific keys from a backup.
 *
 * 

Getting Started

* *

In order to interact with the Azure Key Vault service, you will need to create an instance of the * {@link KeyVaultBackupAsyncClient} class, a vault url and a credential object.

* *

The examples shown in this document use a credential object named DefaultAzureCredential for authentication, * which is appropriate for most scenarios, including local development and production environments. Additionally, * we recommend using a * * managed identity for authentication in production environments. * You can find more information on different ways of authenticating and their corresponding credential types in the * * Azure Identity documentation".

* *

Sample: Construct Asynchronous Backup Client

* *

The following code sample demonstrates the creation of a {@link KeyVaultBackupAsyncClient}, using the * {@link KeyVaultBackupClientBuilder} to configure it.

* * *
 * KeyVaultBackupAsyncClient keyVaultBackupAsyncClient = new KeyVaultBackupClientBuilder()
 *     .vaultUrl("<your-managed-hsm-url>")
 *     .credential(new DefaultAzureCredentialBuilder().build())
 *     .buildAsyncClient();
 * 
* * *
* *
* *

Back Up a Collection of Keys

* The {@link KeyVaultBackupAsyncClient} can be used to back up the entire collection of keys from a key vault. * *

Code Sample:

*

The following code sample demonstrates how to asynchronously back up an entire collection of keys using, using the * {@link KeyVaultBackupAsyncClient#beginBackup(String, String)} API.

* * *
 * String blobStorageUrl = "https://myaccount.blob.core.windows.net/myContainer";
 * String sasToken = "sv=2020-02-10&ss=b&srt=o&sp=rwdlactfx&se=2021-06-17T07:13:07Z&st=2021-06-16T23:13:07Z"
 *     + "&spr=https&sig=n5V6fnlkViEF9b7ij%2FttTHNwO2BdFIHKHppRxGAyJdc%3D";
 *
 * client.beginBackup(blobStorageUrl, sasToken)
 *     .setPollInterval(Duration.ofSeconds(1)) // You can set a custom polling interval.
 *     .doOnError(e -> System.out.printf("Backup failed with error: %s.%n", e.getMessage()))
 *     .doOnNext(pollResponse ->
 *         System.out.printf("The current status of the operation is: %s.%n", pollResponse.getStatus()))
 *     .filter(pollResponse -> pollResponse.getStatus() == LongRunningOperationStatus.SUCCESSFULLY_COMPLETED)
 *     .flatMap(AsyncPollResponse::getFinalResult)
 *     .subscribe(folderUrl ->
 *         System.out.printf("Backup completed. The storage location of this backup is: %s.%n", folderUrl));
 * 
* * *

Note: For the synchronous sample, refer to {@link KeyVaultBackupClient}.

* *
* *
* *

Restore a Collection of Keys

* The {@link KeyVaultBackupClient} can be used to restore an entire collection of keys from a backup. * *

Code Sample:

*

The following code sample demonstrates how to asynchronously restore an entire collection of keys from a backup, * using the {@link KeyVaultBackupClient#beginRestore(String, String)} API.

* * *
 * String folderUrl = "https://myaccount.blob.core.windows.net/myContainer/mhsm-myaccount-2020090117323313";
 * String sasToken = "sv=2020-02-10&ss=b&srt=o&sp=rwdlactfx&se=2021-06-17T07:13:07Z&st=2021-06-16T23:13:07Z"
 *     + "&spr=https&sig=n5V6fnlkViEF9b7ij%2FttTHNwO2BdFIHKHppRxGAyJdc%3D";
 *
 * client.beginRestore(folderUrl, sasToken)
 *     .setPollInterval(Duration.ofSeconds(1)) // You can set a custom polling interval.
 *     .doOnError(e -> System.out.printf("Restore failed with error: %s.%n", e.getMessage()))
 *     .doOnNext(pollResponse ->
 *         System.out.printf("The current status of the operation is: %s.%n", pollResponse.getStatus()))
 *     .filter(pollResponse -> pollResponse.getStatus() == LongRunningOperationStatus.SUCCESSFULLY_COMPLETED)
 *     .flatMap(AsyncPollResponse::getFinalResult)
 *     .subscribe(unused -> System.out.printf("Backup restored successfully.%n"));
 * 
* * *

Note: For the synchronous sample, refer to {@link KeyVaultBackupClient}.

* *
* *
* *

Selectively Restore a Key

* The {@link KeyVaultBackupAsyncClient} can be used to restore a specific key from a backup. * *

Code Sample:

*

The following code sample demonstrates how to asynchronously restore a specific key from a backup, using * the {@link KeyVaultBackupAsyncClient#beginSelectiveKeyRestore(String, String, String)} API.

* * *
 * String folderUrl = "https://myaccount.blob.core.windows.net/myContainer/mhsm-myaccount-2020090117323313";
 * String sasToken = "sv=2020-02-10&ss=b&srt=o&sp=rwdlactfx&se=2021-06-17T07:13:07Z&st=2021-06-16T23:13:07Z"
 *     + "&spr=https&sig=n5V6fnlkViEF9b7ij%2FttTHNwO2BdFIHKHppRxGAyJdc%3D";
 * String keyName = "myKey";
 *
 * client.beginSelectiveKeyRestore(folderUrl, sasToken, keyName)
 *     .setPollInterval(Duration.ofSeconds(1)) // You can set a custom polling interval.
 *     .doOnError(e -> System.out.printf("Key restoration failed with error: %s.%n", e.getMessage()))
 *     .doOnNext(pollResponse ->
 *         System.out.printf("The current status of the operation is: %s.%n", pollResponse.getStatus()))
 *     .filter(pollResponse -> pollResponse.getStatus() == LongRunningOperationStatus.SUCCESSFULLY_COMPLETED)
 *     .flatMap(AsyncPollResponse::getFinalResult)
 *     .subscribe(unused -> System.out.printf("Key restored successfully.%n"));
 * 
* * *

Note: For the synchronous sample, refer to {@link KeyVaultBackupClient}.

* *
* *
* * @see com.azure.security.keyvault.administration * @see KeyVaultBackupClientBuilder */ @ServiceClient(builder = KeyVaultBackupClientBuilder.class, isAsync = true) public final class KeyVaultBackupAsyncClient { /** * The logger to be used. */ private static final ClientLogger LOGGER = new ClientLogger(KeyVaultBackupAsyncClient.class); private static final Duration DEFAULT_POLLING_INTERVAL = Duration.ofSeconds(1); /** * The underlying AutoRest client used to interact with the Key Vault service. */ private final KeyVaultBackupClientImpl clientImpl; /** * The Key Vault URL this client is associated to. */ private final String vaultUrl; /** * The Key Vault Administration Service version to use with this client. */ private final String serviceVersion; /** * The {@link HttpPipeline} powering this client. */ private final HttpPipeline pipeline; Duration getDefaultPollingInterval() { return DEFAULT_POLLING_INTERVAL; } /** * Package private constructor to be used by {@link KeyVaultBackupClientBuilder}. */ KeyVaultBackupAsyncClient(URL vaultUrl, HttpPipeline httpPipeline, KeyVaultAdministrationServiceVersion serviceVersion) { Objects.requireNonNull(vaultUrl, KeyVaultErrorCodeStrings.VAULT_END_POINT_REQUIRED); this.vaultUrl = vaultUrl.toString(); this.serviceVersion = serviceVersion.getVersion(); this.pipeline = httpPipeline; clientImpl = new KeyVaultBackupClientImpl(httpPipeline, this.serviceVersion); } /** * Gets the URL for the Key Vault this client is associated with. * * @return The Key Vault URL. */ public String getVaultUrl() { return this.vaultUrl; } /** * Gets the {@link HttpPipeline} powering this client. * * @return The pipeline. */ HttpPipeline getHttpPipeline() { return this.pipeline; } /** * Initiates a full backup of the Key Vault. * *

Code Samples

*

Starts a {@link KeyVaultBackupOperation backup operation}, polls for its status and waits for it to complete. * Prints out the details of the operation's final result in case of success or prints out details of an error in * case the operation fails.

* *
     * String blobStorageUrl = "https://myaccount.blob.core.windows.net/myContainer";
     * String sasToken = "sv=2020-02-10&ss=b&srt=o&sp=rwdlactfx&se=2021-06-17T07:13:07Z&st=2021-06-16T23:13:07Z"
     *     + "&spr=https&sig=n5V6fnlkViEF9b7ij%2FttTHNwO2BdFIHKHppRxGAyJdc%3D";
     *
     * client.beginBackup(blobStorageUrl, sasToken)
     *     .setPollInterval(Duration.ofSeconds(1)) // You can set a custom polling interval.
     *     .doOnError(e -> System.out.printf("Backup failed with error: %s.%n", e.getMessage()))
     *     .doOnNext(pollResponse ->
     *         System.out.printf("The current status of the operation is: %s.%n", pollResponse.getStatus()))
     *     .filter(pollResponse -> pollResponse.getStatus() == LongRunningOperationStatus.SUCCESSFULLY_COMPLETED)
     *     .flatMap(AsyncPollResponse::getFinalResult)
     *     .subscribe(folderUrl ->
     *         System.out.printf("Backup completed. The storage location of this backup is: %s.%n", folderUrl));
     * 
* * * @param blobStorageUrl The URL for the Blob Storage resource where the backup will be located. * @param sasToken Optional Shared Access Signature (SAS) token to authorize access to the blob. If {@code null}, * Managed Identity will be used to authenticate instead. * * @return A {@link PollerFlux} polling on the {@link KeyVaultBackupOperation backup operation} status. * * @throws KeyVaultAdministrationException If the given {@code blobStorageUrl} or {@code sasToken} are invalid. * @throws NullPointerException If the {@code blobStorageUrl} is {@code null}. */ @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) public PollerFlux beginBackup(String blobStorageUrl, String sasToken) { if (blobStorageUrl == null) { throw LOGGER.logExceptionAsError( new NullPointerException( String.format(KeyVaultErrorCodeStrings.PARAMETER_REQUIRED, "'blobStorageUrl'"))); } return new PollerFlux<>(getDefaultPollingInterval(), backupActivationOperation(blobStorageUrl, sasToken), backupPollOperation(), (pollingContext, firstResponse) -> Mono.error(LOGGER.logExceptionAsError(new RuntimeException("Cancellation is not supported"))), backupFetchOperation()); } /** * Initiates a full backup of the Key Vault. * * @param blobStorageUrl The URL for the Blob Storage resource where the backup will be located. * @param sasToken Optional Shared Access Signature (SAS) token to authorize access to the blob. If {@code null}, * Managed Identity will be used to authenticate instead. * @param context Additional context that is passed through the HTTP pipeline during the service call. * * @return A {@link PollerFlux} polling on the {@link KeyVaultBackupOperation backup operation} status. * * @throws KeyVaultAdministrationException If the given {@code blobStorageUrl} or {@code sasToken} are invalid. */ Mono> backupWithResponse(String blobStorageUrl, String sasToken, Context context) { SASTokenParameter sasTokenParameter = new SASTokenParameter(blobStorageUrl) .setToken(sasToken) .setUseManagedIdentity(sasToken == null); try { return clientImpl.fullBackupWithResponseAsync(vaultUrl, sasTokenParameter, context) .doOnRequest(ignored -> LOGGER.verbose("Backing up at URL - {}", blobStorageUrl)) .doOnSuccess(response -> LOGGER.verbose("Backed up at URL - {}", response.getValue().getAzureStorageBlobContainerUri())) .doOnError(error -> LOGGER.warning("Failed to backup at URL - {}", blobStorageUrl, error)) .map(backupOperationResponse -> new SimpleResponse<>(backupOperationResponse.getRequest(), backupOperationResponse.getStatusCode(), backupOperationResponse.getHeaders(), (KeyVaultBackupOperation) transformToLongRunningOperation(backupOperationResponse.getValue()))); } catch (RuntimeException e) { return monoError(LOGGER, e); } } private Function, Mono> backupActivationOperation( String blobStorageUrl, String sasToken) { return (pollingContext) -> { try { return withContext(context -> backupWithResponse(blobStorageUrl, sasToken, context)) .flatMap(backupResponse -> Mono.just(backupResponse.getValue())); } catch (RuntimeException e) { return monoError(LOGGER, e); } }; } private Function, Mono>> backupPollOperation() { return (pollingContext) -> { try { PollResponse pollResponse = pollingContext.getLatestResponse(); if (pollResponse.getStatus() == LongRunningOperationStatus.SUCCESSFULLY_COMPLETED || pollResponse.getStatus() == LongRunningOperationStatus.FAILED) { return Mono.just(pollResponse); } final KeyVaultBackupOperation keyVaultBackupOperation = pollResponse.getValue(); if (keyVaultBackupOperation == null) { LOGGER.warning("Backup operation does not exist. Activation operation failed."); return Mono.just(new PollResponse( LongRunningOperationStatus.fromString("BACKUP_START_FAILED", true), null)); } final String jobId = keyVaultBackupOperation.getOperationId(); return withContext(context -> clientImpl.fullBackupStatusWithResponseAsync(vaultUrl, jobId, context)) .map(response -> new SimpleResponse<>(response, (KeyVaultBackupOperation) transformToLongRunningOperation(response.getValue()))) .flatMap(KeyVaultBackupAsyncClient::processBackupOperationResponse); } catch (HttpResponseException e) { //noinspection ThrowableNotThrown LOGGER.logExceptionAsError(e); return Mono.just(new PollResponse<>(LongRunningOperationStatus.FAILED, null)); } catch (RuntimeException e) { return monoError(LOGGER, e); } }; } private Function, Mono> backupFetchOperation() { return (pollingContext) -> { try { String blobContainerUri = pollingContext.getLatestResponse().getValue().getAzureStorageBlobContainerUrl(); if (blobContainerUri == null) { return Mono.empty(); } else { return Mono.just(blobContainerUri); } } catch (RuntimeException e) { return monoError(LOGGER, e); } }; } private static Mono> processBackupOperationResponse( Response response) { String operationStatus = response.getValue().getStatus().toLowerCase(Locale.US); return Mono.just(new PollResponse<>( toLongRunningOperationStatus(operationStatus.toLowerCase(Locale.US)), response.getValue())); } /** * Initiates a full restore of the Key Vault. * *

Code Samples

*

Starts a {@link KeyVaultRestoreOperation restore operation}, polls for its status and waits for it to * complete. Prints out error details in case the operation fails.

* *
     * String folderUrl = "https://myaccount.blob.core.windows.net/myContainer/mhsm-myaccount-2020090117323313";
     * String sasToken = "sv=2020-02-10&ss=b&srt=o&sp=rwdlactfx&se=2021-06-17T07:13:07Z&st=2021-06-16T23:13:07Z"
     *     + "&spr=https&sig=n5V6fnlkViEF9b7ij%2FttTHNwO2BdFIHKHppRxGAyJdc%3D";
     *
     * client.beginRestore(folderUrl, sasToken)
     *     .setPollInterval(Duration.ofSeconds(1)) // You can set a custom polling interval.
     *     .doOnError(e -> System.out.printf("Restore failed with error: %s.%n", e.getMessage()))
     *     .doOnNext(pollResponse ->
     *         System.out.printf("The current status of the operation is: %s.%n", pollResponse.getStatus()))
     *     .filter(pollResponse -> pollResponse.getStatus() == LongRunningOperationStatus.SUCCESSFULLY_COMPLETED)
     *     .flatMap(AsyncPollResponse::getFinalResult)
     *     .subscribe(unused -> System.out.printf("Backup restored successfully.%n"));
     * 
* * * @param folderUrl The URL for the Blob Storage resource where the backup is located, including the path to * the blob container where the backup resides. This would be the exact value that is returned as the result of a * backup operation. An example of such a URL may look like the following: * https://contoso.blob.core.windows.net/backup/mhsm-contoso-2020090117323313. * @param sasToken Optional Shared Access Signature (SAS) token to authorize access to the blob. If {@code null}, * Managed Identity will be used to authenticate instead. * * @return A {@link PollerFlux} polling on the {@link KeyVaultRestoreOperation restore operation} status. * * @throws KeyVaultAdministrationException If the given {@code folderUrl} or {@code sasToken} are invalid. * @throws NullPointerException If the {@code folderUrl} is {@code null}. */ @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) public PollerFlux beginRestore(String folderUrl, String sasToken) { if (folderUrl == null) { throw LOGGER.logExceptionAsError( new NullPointerException(String.format(KeyVaultErrorCodeStrings.PARAMETER_REQUIRED, "'folderUrl'"))); } return new PollerFlux<>(getDefaultPollingInterval(), restoreActivationOperation(folderUrl, sasToken), restorePollOperation(), (pollingContext, firstResponse) -> Mono.error(LOGGER.logExceptionAsError(new RuntimeException("Cancellation is not supported"))), (pollingContext) -> Mono.just(new KeyVaultRestoreResult())); } /** * Initiates a full restore of the Key Vault. * * @param folderUrl The URL for the Blob Storage resource where the backup is located, including the path to * the blob container where the backup resides. This would be the exact value that is returned as the result of a * backup operation. An example of such a URL may look like the following: * https://contoso.blob.core.windows.net/backup/mhsm-contoso-2020090117323313. * @param sasToken Optional Shared Access Signature (SAS) token to authorize access to the blob. If {@code null}, * Managed Identity will be used to authenticate instead. * @param context Additional context that is passed through the HTTP pipeline during the service call. * * @return A {@link PollerFlux} polling on the {@link KeyVaultRestoreOperation backup operation} status. * * @throws KeyVaultAdministrationException If the given {@code folderUrl} or {@code sasToken} are invalid. */ Mono> restoreWithResponse(String folderUrl, String sasToken, Context context) { String[] segments = folderUrl.split("/"); String folderName = segments[segments.length - 1]; String containerUrl = folderUrl.substring(0, folderUrl.length() - folderName.length()); SASTokenParameter sasTokenParameter = new SASTokenParameter(containerUrl) .setToken(sasToken) .setUseManagedIdentity(sasToken == null); RestoreOperationParameters restoreOperationParameters = new RestoreOperationParameters(sasTokenParameter, folderName); try { return clientImpl.fullRestoreOperationWithResponseAsync(vaultUrl, restoreOperationParameters, context) .doOnRequest(ignored -> LOGGER.verbose("Restoring from location - {}", folderUrl)) .doOnSuccess(response -> LOGGER.verbose("Restored from location - {}", folderUrl)) .doOnError(error -> LOGGER.warning("Failed to restore from location - {}", folderUrl, error)) .map(restoreOperationResponse -> new SimpleResponse<>(restoreOperationResponse.getRequest(), restoreOperationResponse.getStatusCode(), restoreOperationResponse.getHeaders(), (KeyVaultRestoreOperation) transformToLongRunningOperation( restoreOperationResponse.getValue()))); } catch (RuntimeException e) { return monoError(LOGGER, e); } } private Function, Mono> restoreActivationOperation(String folderUrl, String sasToken) { return (pollingContext) -> { try { return withContext(context -> restoreWithResponse(folderUrl, sasToken, context)) .flatMap(restoreResponse -> Mono.just(restoreResponse.getValue())); } catch (RuntimeException e) { return monoError(LOGGER, e); } }; } private Function, Mono>> restorePollOperation() { return (pollingContext) -> { try { PollResponse pollResponse = pollingContext.getLatestResponse(); if (pollResponse.getStatus() == LongRunningOperationStatus.SUCCESSFULLY_COMPLETED || pollResponse.getStatus() == LongRunningOperationStatus.FAILED) { return Mono.just(pollResponse); } final KeyVaultRestoreOperation keyVaultRestoreOperation = pollResponse.getValue(); if (keyVaultRestoreOperation == null) { LOGGER.warning("Restore operation does not exist. Activation operation failed."); return Mono.just(new PollResponse( LongRunningOperationStatus.fromString("RESTORE_START_FAILED", true), null)); } final String jobId = keyVaultRestoreOperation.getOperationId(); return withContext(context -> clientImpl.restoreStatusWithResponseAsync(vaultUrl, jobId, context)) .map(response -> new SimpleResponse<>(response, (KeyVaultRestoreOperation) transformToLongRunningOperation(response.getValue()))) .flatMap(KeyVaultBackupAsyncClient::processRestoreOperationResponse); } catch (HttpResponseException e) { //noinspection ThrowableNotThrown LOGGER.logExceptionAsError(e); return Mono.just(new PollResponse<>(LongRunningOperationStatus.FAILED, null)); } catch (RuntimeException e) { return monoError(LOGGER, e); } }; } static Mono> processRestoreOperationResponse( Response response) { String operationStatus = response.getValue().getStatus().toLowerCase(Locale.US); return Mono.just(new PollResponse<>( toLongRunningOperationStatus(operationStatus.toLowerCase(Locale.US)), response.getValue())); } /** * Restores all versions of a given key using the supplied SAS token pointing to a previously stored Azure Blob * storage backup folder. * *

Code Samples

*

Starts a {@link KeyVaultSelectiveKeyRestoreOperation selective key restore operation}, polls for its status * and waits for it to complete. Prints out error details in case the operation fails.

* *
     * String folderUrl = "https://myaccount.blob.core.windows.net/myContainer/mhsm-myaccount-2020090117323313";
     * String sasToken = "sv=2020-02-10&ss=b&srt=o&sp=rwdlactfx&se=2021-06-17T07:13:07Z&st=2021-06-16T23:13:07Z"
     *     + "&spr=https&sig=n5V6fnlkViEF9b7ij%2FttTHNwO2BdFIHKHppRxGAyJdc%3D";
     * String keyName = "myKey";
     *
     * client.beginSelectiveKeyRestore(folderUrl, sasToken, keyName)
     *     .setPollInterval(Duration.ofSeconds(1)) // You can set a custom polling interval.
     *     .doOnError(e -> System.out.printf("Key restoration failed with error: %s.%n", e.getMessage()))
     *     .doOnNext(pollResponse ->
     *         System.out.printf("The current status of the operation is: %s.%n", pollResponse.getStatus()))
     *     .filter(pollResponse -> pollResponse.getStatus() == LongRunningOperationStatus.SUCCESSFULLY_COMPLETED)
     *     .flatMap(AsyncPollResponse::getFinalResult)
     *     .subscribe(unused -> System.out.printf("Key restored successfully.%n"));
     * 
* * * @param keyName The name of the key to be restored. * @param folderUrl The URL for the Blob Storage resource where the backup is located, including the path to * the blob container where the backup resides. This would be the exact value that is returned as the result of a * backup operation. An example of such a URL may look like the following: * https://contoso.blob.core.windows.net/backup/mhsm-contoso-2020090117323313. * @param sasToken Optional Shared Access Signature (SAS) token to authorize access to the blob. If {@code null}, * Managed Identity will be used to authenticate instead. * * @return A {@link PollerFlux} polling on the {@link KeyVaultRestoreOperation restore operation} status. * * @throws KeyVaultAdministrationException If the given {@code keyName}, {@code folderUrl} or {@code sasToken} are * invalid. * @throws NullPointerException If the {@code keyName} or {@code folderUrl} are {@code null}. */ @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION) public PollerFlux beginSelectiveKeyRestore(String keyName, String folderUrl, String sasToken) { if (keyName == null) { throw LOGGER.logExceptionAsError( new NullPointerException(String.format(KeyVaultErrorCodeStrings.PARAMETER_REQUIRED, "'keyName'"))); } if (folderUrl == null) { throw LOGGER.logExceptionAsError( new NullPointerException(String.format(KeyVaultErrorCodeStrings.PARAMETER_REQUIRED, "'folderUrl'"))); } return new PollerFlux<>(getDefaultPollingInterval(), selectiveKeyRestoreActivationOperation(keyName, folderUrl, sasToken), selectiveKeyRestorePollOperation(), (pollingContext, firstResponse) -> Mono.error(LOGGER.logExceptionAsError(new RuntimeException("Cancellation is not supported"))), (pollingContext) -> Mono.just(new KeyVaultSelectiveKeyRestoreResult())); } /** * Restores all versions of a given key using the supplied SAS token pointing to a previously stored Azure Blob * storage backup folder. * * @param keyName The name of the key to be restored. * @param folderUrl The URL for the Blob Storage resource where the backup is located, including the path to * the blob container where the backup resides. This would be the exact value that is returned as the result of a * backup operation. An example of such a URL may look like the following: * https://contoso.blob.core.windows.net/backup/mhsm-contoso-2020090117323313. * @param sasToken Optional Shared Access Signature (SAS) token to authorize access to the blob. If {@code null}, * Managed Identity will be used to authenticate instead. * @param context Additional context that is passed through the HTTP pipeline during the service call. * * @return A {@link PollerFlux} polling on the {@link KeyVaultRestoreOperation backup operation} status. */ Mono> selectiveKeyRestoreWithResponse(String keyName, String folderUrl, String sasToken, Context context) { String[] segments = folderUrl.split("/"); String folderName = segments[segments.length - 1]; String containerUrl = folderUrl.substring(0, folderUrl.length() - folderName.length()); SASTokenParameter sasTokenParameter = new SASTokenParameter(containerUrl) .setToken(sasToken) .setUseManagedIdentity(sasToken == null); SelectiveKeyRestoreOperationParameters selectiveKeyRestoreOperationParameters = new SelectiveKeyRestoreOperationParameters(sasTokenParameter, folderName); try { return clientImpl.selectiveKeyRestoreOperationWithResponseAsync(vaultUrl, keyName, selectiveKeyRestoreOperationParameters, context) .doOnRequest(ignored -> LOGGER.verbose("Restoring key \"{}\" from location - {}", keyName, folderUrl)) .doOnSuccess(response -> LOGGER.verbose("Restored key \"{}\" from location - {}", keyName, folderUrl)) .doOnError(error -> LOGGER.warning("Failed to restore key \"{}\" from location - {}", keyName, folderUrl, error)) .map(restoreOperationResponse -> new SimpleResponse<>(restoreOperationResponse.getRequest(), restoreOperationResponse.getStatusCode(), restoreOperationResponse.getHeaders(), (KeyVaultSelectiveKeyRestoreOperation) transformToLongRunningOperation( restoreOperationResponse.getValue()))); } catch (RuntimeException e) { return monoError(LOGGER, e); } } private Function, Mono> selectiveKeyRestoreActivationOperation(String keyName, String folderUrl, String sasToken) { return (pollingContext) -> { try { return withContext(context -> selectiveKeyRestoreWithResponse(keyName, folderUrl, sasToken, context)) .flatMap(selectiveKeyRestoreResponse -> Mono.just(selectiveKeyRestoreResponse.getValue())); } catch (RuntimeException e) { return monoError(LOGGER, e); } }; } private Function, Mono>> selectiveKeyRestorePollOperation() { return (pollingContext) -> { try { PollResponse pollResponse = pollingContext.getLatestResponse(); if (pollResponse.getStatus() == LongRunningOperationStatus.SUCCESSFULLY_COMPLETED || pollResponse.getStatus() == LongRunningOperationStatus.FAILED) { return Mono.just(pollResponse); } final KeyVaultSelectiveKeyRestoreOperation keyVaultSelectiveKeyRestoreOperation = pollResponse.getValue(); if (keyVaultSelectiveKeyRestoreOperation == null) { LOGGER.warning("Restore operation does not exist. Activation operation failed."); return Mono.just(new PollResponse( LongRunningOperationStatus.fromString("SELECTIVE_RESTORE_START_FAILED", true), null)); } final String jobId = keyVaultSelectiveKeyRestoreOperation.getOperationId(); return withContext(context -> clientImpl.restoreStatusWithResponseAsync(vaultUrl, jobId, context)) .map(response -> new SimpleResponse<>(response, (KeyVaultSelectiveKeyRestoreOperation) restoreOperationToSelectiveKeyRestoreOperation(response.getValue()))) .flatMap(KeyVaultBackupAsyncClient::processSelectiveKeyRestoreOperationResponse); } catch (HttpResponseException e) { //noinspection ThrowableNotThrown LOGGER.logExceptionAsError(e); return Mono.just(new PollResponse<>(LongRunningOperationStatus.FAILED, null)); } catch (RuntimeException e) { return monoError(LOGGER, e); } }; } private static Mono> processSelectiveKeyRestoreOperationResponse( Response response) { String operationStatus = response.getValue().getStatus().toLowerCase(Locale.US); return Mono.just(new PollResponse<>( toLongRunningOperationStatus(operationStatus.toLowerCase(Locale.US)), response.getValue())); } static KeyVaultLongRunningOperation restoreOperationToSelectiveKeyRestoreOperation(RestoreOperation operation) { return new KeyVaultSelectiveKeyRestoreOperation(operation.getStatus(), operation.getStatusDetails(), createKeyVaultErrorFromError(operation.getError()), operation.getJobId(), operation.getStartTime(), operation.getEndTime()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy