KeyEncryptionKeyClientBuilder.java
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.security.keyvault.keys.cryptography;
import com.azure.core.annotation.ServiceClientBuilder;
import com.azure.core.credential.TokenCredential;
import com.azure.core.cryptography.AsyncKeyEncryptionKey;
import com.azure.core.cryptography.AsyncKeyEncryptionKeyResolver;
import com.azure.core.cryptography.KeyEncryptionKey;
import com.azure.core.cryptography.KeyEncryptionKeyResolver;
import com.azure.core.http.HttpClient;
import com.azure.core.http.HttpPipeline;
import com.azure.core.http.policy.HttpLogDetailLevel;
import com.azure.core.http.policy.HttpLogOptions;
import com.azure.core.http.policy.HttpLoggingPolicy;
import com.azure.core.http.policy.HttpPipelinePolicy;
import com.azure.core.http.policy.RetryPolicy;
import com.azure.core.http.policy.UserAgentPolicy;
import com.azure.core.util.ClientOptions;
import com.azure.core.util.Configuration;
import com.azure.core.util.logging.ClientLogger;
import com.azure.security.keyvault.keys.models.JsonWebKey;
import reactor.core.publisher.Mono;
/**
* This class provides a fluent builder API to help aid the configuration and instantiation of the
* {@link AsyncKeyEncryptionKey KeyEncryptionKey async client} and
* {@link KeyEncryptionKey KeyEncryptionKey sync client}, by calling
* {@link KeyEncryptionKeyClientBuilder#buildAsyncKeyEncryptionKey(String)} and
* {@link KeyEncryptionKeyClientBuilder#buildKeyEncryptionKey(String)} respectively. It constructs an instance of the
* desired client.
*
* <p>The minimal configuration options required by {@link KeyEncryptionKeyClientBuilder} to build
* {@link AsyncKeyEncryptionKey} are {@link JsonWebKey jsonWebKey} or {@link String Azure Key Vault key identifier}
* and {@link TokenCredential credential}.</p>
*
* <p>The {@link HttpLogDetailLevel log detail level}, multiple custom {@link HttpLoggingPolicy policies} and custom
* {@link HttpClient http client} can be optionally configured in the {@link KeyEncryptionKeyClientBuilder}.</p>
*
* <p>Alternatively, a custom {@link HttpPipeline http pipeline} with custom {@link HttpPipelinePolicy} policies
* can be specified. It provides finer control over the construction of {@link AsyncKeyEncryptionKey} and
* {@link KeyEncryptionKey}</p>
*
* <p> The minimal configuration options required by {@link KeyEncryptionKeyClientBuilder keyEncryptionKeyClientBuilder}
* to build {@link KeyEncryptionKey} are {@link JsonWebKey jsonWebKey} or
* {@link String Azure Key Vault key identifier} and {@link TokenCredential credential}.</p>
*
* @see KeyEncryptionKeyAsyncClient
* @see KeyEncryptionKeyClient
*/
@ServiceClientBuilder(serviceClients = {KeyEncryptionKeyClient.class, KeyEncryptionKeyAsyncClient.class})
public final class KeyEncryptionKeyClientBuilder implements KeyEncryptionKeyResolver, AsyncKeyEncryptionKeyResolver {
private final ClientLogger logger = new ClientLogger(KeyEncryptionKeyClientBuilder.class);
private final CryptographyClientBuilder builder;
/**
* The constructor with defaults.
*/
public KeyEncryptionKeyClientBuilder() {
builder = new CryptographyClientBuilder();
}
/**
* Creates a {@link KeyEncryptionKey} based on options set in the builder. Every time
* {@code buildKeyEncryptionKey(String)} is called, a new instance of {@link KeyEncryptionKey} is created.
*
* <p>If {@link KeyEncryptionKeyClientBuilder#pipeline(HttpPipeline) pipeline} is set, then the {@code pipeline}
* and {@code keyId} are used to create the {@link KeyEncryptionKeyClient client}. All other builder settings are
* ignored. If {@code pipeline} is not set, then an
* {@link KeyEncryptionKeyClientBuilder#credential(TokenCredential) Azure Key Vault credential} and {@code keyId}
* are required to build the {@link KeyEncryptionKeyClient client}.</p>
*
* @return A {@link KeyEncryptionKeyClient} with the options set from the builder.
*
* @throws IllegalStateException If {@link KeyEncryptionKeyClientBuilder#credential(TokenCredential)} or
* {@code keyId} have not been set.
*/
@Override
public KeyEncryptionKey buildKeyEncryptionKey(String keyId) {
return new KeyEncryptionKeyClient((KeyEncryptionKeyAsyncClient) buildAsyncKeyEncryptionKey(keyId).block());
}
/**
* Creates a local {@link KeyEncryptionKeyClient} for a given JSON Web Key. Every time
* {@code buildKeyEncryptionKey(JsonWebKey)} is called, a new instance of {@link KeyEncryptionKey} is created.
* For local clients, all other builder settings are ignored.
*
* <p>The {@code key} is required to build the {@link KeyEncryptionKeyClient client}.</p>
*
* @param key The {@link JsonWebKey} to be used for cryptography operations.
*
* @return A {@link KeyEncryptionKeyClient} with the options set from the builder.
*
* @throws IllegalStateException If {{@code key} is not set.
*/
public KeyEncryptionKey buildKeyEncryptionKey(JsonWebKey key) {
return new KeyEncryptionKeyClient((KeyEncryptionKeyAsyncClient) buildAsyncKeyEncryptionKey(key).block());
}
/**
* Creates a {@link KeyEncryptionKeyAsyncClient} based on options set in the builder. Every time
* {@code buildAsyncKeyEncryptionKey(String)} is called, a new instance of {@link KeyEncryptionKeyAsyncClient} is
* created.
*
* <p>If {@link KeyEncryptionKeyClientBuilder#pipeline(HttpPipeline) pipeline} is set, then the {@code pipeline}
* and {@code keyId} are used to create the {@link KeyEncryptionKeyAsyncClient async client}. All other builder
* settings are ignored. If {@code pipeline} is not set, then an
* {@link KeyEncryptionKeyClientBuilder#credential(TokenCredential) Azure Key Vault credentials} and
* {@code keyId} are required to build the {@link KeyEncryptionKeyAsyncClient async client}.</p>
*
* @return A {@link KeyEncryptionKeyAsyncClient} with the options set from the builder.
*
* @throws IllegalStateException If {@link KeyEncryptionKeyClientBuilder#credential(TokenCredential)} is
* {@code null} or {@code keyId} is empty or {@code null}.
*/
@Override
public Mono<? extends AsyncKeyEncryptionKey> buildAsyncKeyEncryptionKey(String keyId) {
builder.keyIdentifier(keyId);
if (Strings.isNullOrEmpty(keyId)) {
throw logger.logExceptionAsError(new IllegalStateException(
"An Azure Key Vault key identifier cannot be null and is required to build the key encryption key "
+ "client."));
}
CryptographyServiceVersion serviceVersion = builder.getServiceVersion() != null ? builder.getServiceVersion() : CryptographyServiceVersion.getLatest();
if (builder.getPipeline() != null) {
return Mono.defer(() -> Mono.just(new KeyEncryptionKeyAsyncClient(keyId, builder.getPipeline(), serviceVersion)));
}
if (builder.getCredential() == null) {
throw logger.logExceptionAsError(new IllegalStateException(
"Azure Key Vault credentials cannot be null and are required to build a key encryption key client."));
}
HttpPipeline pipeline = builder.setupPipeline();
return Mono.defer(() -> Mono.just(new KeyEncryptionKeyAsyncClient(keyId, pipeline, serviceVersion)));
}
/**
* Creates a local {@link KeyEncryptionKeyAsyncClient} based on options set in the builder. Every time
* {@code buildAsyncKeyEncryptionKey(String)} is called, a new instance of
* {@link KeyEncryptionKeyAsyncClient} is created. For local clients, all other builder settings are ignored.
*
* <p>The {@code key} is required to build the {@link KeyEncryptionKeyAsyncClient client}.</p>
*
* @param key The key to be used for cryptography operations.
*
* @return A {@link KeyEncryptionKeyAsyncClient} with the options set from the builder.
*
* @throws IllegalArgumentException If {@code key} has no id.
* @throws IllegalStateException If {@code key} is {@code null}.
*/
public Mono<? extends AsyncKeyEncryptionKey> buildAsyncKeyEncryptionKey(JsonWebKey key) {
if (key == null) {
throw logger.logExceptionAsError(new IllegalStateException(
"JSON Web Key cannot be null and is required to build a local key encryption key async client."));
} else if (key.getId() == null) {
throw logger.logExceptionAsError(new IllegalArgumentException(
"JSON Web Key's id property is not configured."));
}
return Mono.defer(() -> Mono.just(new KeyEncryptionKeyAsyncClient(key)));
}
/**
* Sets the credential to use when authenticating HTTP requests.
*
* @param credential The credential to use for authenticating HTTP requests.
*
* @return The updated {@link KeyEncryptionKeyClientBuilder} object.
*
* @throws NullPointerException If {@code credential} is {@code null}.
*/
public KeyEncryptionKeyClientBuilder credential(TokenCredential credential) {
if (credential == null) {
throw logger.logExceptionAsError(new NullPointerException("'credential' cannot be null."));
}
builder.credential(credential);
return this;
}
/**
* Sets the logging configuration for HTTP requests and responses.
*
* <p> If logLevel is not provided, default value of {@link HttpLogDetailLevel#NONE} is set.</p>
*
* @param logOptions The logging configuration to use when sending and receiving HTTP requests/responses.
*
* @return The updated {@link KeyEncryptionKeyClientBuilder} object.
*/
public KeyEncryptionKeyClientBuilder httpLogOptions(HttpLogOptions logOptions) {
builder.httpLogOptions(logOptions);
return this;
}
/**
* Adds a policy to the set of existing policies that are executed after the client required policies.
*
* @param policy The {@link HttpPipelinePolicy policy} to be added.
*
* @return The updated {@link KeyEncryptionKeyClientBuilder} object.
*
* @throws NullPointerException If {@code policy} is {@code null}.
*/
public KeyEncryptionKeyClientBuilder addPolicy(HttpPipelinePolicy policy) {
if (policy == null) {
throw logger.logExceptionAsError(new NullPointerException("'policy' cannot be null."));
}
builder.addPolicy(policy);
return this;
}
/**
* Sets the HTTP client to use for sending and receiving requests to and from the service.
*
* @param client The HTTP client to use for requests.
*
* @return The updated {@link KeyEncryptionKeyClientBuilder} object.
*/
public KeyEncryptionKeyClientBuilder httpClient(HttpClient client) {
builder.httpClient(client);
return this;
}
/**
* Sets the HTTP pipeline to use for the service client.
*
* If {@code pipeline} is set, all other settings are ignored, aside from jsonWebKey identifier
* or jsonWebKey to build the clients.
*
* @param pipeline The HTTP pipeline to use for sending service requests and receiving responses.
*
* @return The updated {@link KeyEncryptionKeyClientBuilder} object.
*/
public KeyEncryptionKeyClientBuilder pipeline(HttpPipeline pipeline) {
builder.pipeline(pipeline);
return this;
}
/**
* Sets the configuration store that is used during construction of the service client.
*
* The default configuration store is a clone of the
* {@link Configuration#getGlobalConfiguration() global configuration store}, use {@link Configuration#NONE} to
* bypass using configuration settings during construction.
*
* @param configuration The configuration store used to get configuration details.
*
* @return The updated {@link KeyEncryptionKeyClientBuilder} object.
*/
public KeyEncryptionKeyClientBuilder configuration(Configuration configuration) {
builder.configuration(configuration);
return this;
}
/**
* Sets the {@link CryptographyServiceVersion} that is used when making API requests.
* <p>
* If a service version is not provided, the service version that will be used will be the latest known service
* version based on the version of the client library being used. If no service version is specified, updating to a
* newer version the client library will have the result of potentially moving to a newer service version.
*
* @param version {@link CryptographyServiceVersion} of the service to be used when making requests.
*
* @return The updated {@link KeyEncryptionKeyClientBuilder} object.
*/
public KeyEncryptionKeyClientBuilder serviceVersion(CryptographyServiceVersion version) {
builder.serviceVersion(version);
return this;
}
/**
* Sets the {@link RetryPolicy} that is used when each request is sent. The default retry policy will be used in
* the pipeline, if not provided.
*
* @param retryPolicy User's retry policy applied to each request.
*
* @return The updated {@link KeyEncryptionKeyClientBuilder} object.
*/
public KeyEncryptionKeyClientBuilder retryPolicy(RetryPolicy retryPolicy) {
builder.retryPolicy(retryPolicy);
return this;
}
/**
* Sets the {@link ClientOptions} which enables various options to be set on the client. For example setting an
* {@code applicationId} using {@link ClientOptions#setApplicationId(String)} to configure the
* {@link UserAgentPolicy} for telemetry/monitoring purposes.
*
* <p>More About <a href="https://azure.github.io/azure-sdk/general_azurecore.html#telemetry-policy">Azure Core:
* Telemetry policy</a>
*
* @param clientOptions The {@link ClientOptions} to be set on the client.
*
* @return The updated {@link KeyEncryptionKeyClientBuilder} object.
*/
public KeyEncryptionKeyClientBuilder clientOptions(ClientOptions clientOptions) {
builder.clientOptions(clientOptions);
return this;
}
}