com.azure.security.attestation.AttestationAdministrationClientBuilder Maven / Gradle / Ivy
Show all versions of azure-security-attestation Show documentation
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.security.attestation;
import com.azure.core.annotation.ServiceClientBuilder;
import com.azure.core.client.traits.ConfigurationTrait;
import com.azure.core.client.traits.EndpointTrait;
import com.azure.core.client.traits.HttpTrait;
import com.azure.core.client.traits.TokenCredentialTrait;
import com.azure.core.credential.TokenCredential;
import com.azure.core.http.HttpClient;
import com.azure.core.http.HttpHeader;
import com.azure.core.http.HttpHeaders;
import com.azure.core.http.HttpPipeline;
import com.azure.core.http.HttpPipelineBuilder;
import com.azure.core.http.HttpPipelinePosition;
import com.azure.core.http.policy.AddDatePolicy;
import com.azure.core.http.policy.AddHeadersFromContextPolicy;
import com.azure.core.http.policy.AddHeadersPolicy;
import com.azure.core.http.policy.BearerTokenAuthenticationPolicy;
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.HttpPolicyProviders;
import com.azure.core.http.policy.RequestIdPolicy;
import com.azure.core.http.policy.RetryOptions;
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.CoreUtils;
import com.azure.core.util.HttpClientOptions;
import com.azure.core.util.builder.ClientBuilderUtil;
import com.azure.core.util.logging.ClientLogger;
import com.azure.core.util.serializer.JacksonAdapter;
import com.azure.security.attestation.implementation.AttestationClientImpl;
import com.azure.security.attestation.models.AttestationPolicySetOptions;
import com.azure.security.attestation.models.AttestationTokenValidationOptions;
import com.azure.security.attestation.models.AttestationType;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static com.azure.core.util.CoreUtils.getApplicationId;
/** This class provides a fluent builder API to help add in the configuration and instantiation of the
* administrative APIs implemented by the Attestation Service:
* {@link com.azure.security.attestation.AttestationAdministrationClient} and
* {@link com.azure.security.attestation.AttestationAdministrationAsyncClient} classes calling the
* {@link AttestationClientBuilder#buildClient()} or {@link AttestationClientBuilder#buildAsyncClient()}.
*
*
* More information on attestation policies can be found here
*
*
* There are two main families of APIs available from the Administration client.
*
* - Attestation Policy Management
* - Policy Management Certificate Management
*
*
* The Policy Management APIs provide the ability to retrieve, modify and reset attestation policies.
* The policy management APIs are:
*
* -
* {@link AttestationAdministrationClient#getAttestationPolicy(AttestationType)}
*
* -
* {@link AttestationAdministrationAsyncClient#getAttestationPolicy(AttestationType)}
*
* -
* {@link AttestationAdministrationClient#setAttestationPolicy(AttestationType, AttestationPolicySetOptions)}
*
* -
* {@link AttestationAdministrationAsyncClient#setAttestationPolicy(AttestationType, AttestationPolicySetOptions)}
*
* -
* {@link AttestationAdministrationClient#resetAttestationPolicy(AttestationType, AttestationPolicySetOptions)}
*
* -
* {@link AttestationAdministrationAsyncClient#resetAttestationPolicy(AttestationType, AttestationPolicySetOptions)}
*
*
*
* The Policy Management Certificate APIs provide the ability to manage the certificates which are
* used to establish authorization for Isolated mode attestation service instances. They include apis to
* enumerate, add and remove policy management certificates.
*
*
* The minimal configuration options required by {@link AttestationClientBuilder} are:
*
* - A {@link String} endpoint.
* - A {@link TokenCredential} object.
*
*
* Instantiate a synchronous Attestation Client
*
*
* AttestationAdministrationClient client = new AttestationAdministrationClientBuilder()
* .endpoint(endpoint)
* .credential(new DefaultAzureCredentialBuilder().build())
* .buildClient();
*
*
*
*
* AttestationAdministrationAsyncClient asyncClient = new AttestationAdministrationClientBuilder()
* .endpoint(endpoint)
* .credential(new DefaultAzureCredentialBuilder().build())
* .buildAsyncClient();
*
*
*/
@ServiceClientBuilder(
serviceClients = { AttestationAdministrationClient.class, AttestationAdministrationAsyncClient.class, })
public final class AttestationAdministrationClientBuilder implements
ConfigurationTrait, EndpointTrait,
HttpTrait, TokenCredentialTrait {
private static final String SDK_NAME = "name";
private static final String SDK_VERSION = "version";
private static final RetryPolicy DEFAULT_RETRY_POLICY = new RetryPolicy("retry-after-ms", ChronoUnit.MILLIS);
private final String[] dataplaneScope = new String[] { "https://attest.azure.net/.default" };
private final ClientLogger logger = new ClientLogger(AttestationAdministrationClientBuilder.class);
private final List perCallPolicies = new ArrayList<>();
private final List perRetryPolicies = new ArrayList<>();
private ClientOptions clientOptions;
private String endpoint;
private HttpClient httpClient;
private HttpLogOptions httpLogOptions;
private HttpPipeline pipeline;
private HttpPipelinePolicy retryPolicy;
private RetryOptions retryOptions;
private Configuration configuration;
private AttestationServiceVersion serviceVersion;
private AttestationTokenValidationOptions tokenValidationOptions;
private TokenCredential tokenCredential = null;
private static final String CLIENT_NAME;
private static final String CLIENT_VERSION;
static {
Map properties = CoreUtils.getProperties("azure-security-attestation.properties");
CLIENT_NAME = properties.getOrDefault(SDK_NAME, "UnknownName");
CLIENT_VERSION = properties.getOrDefault(SDK_VERSION, "UnknownVersion");
}
/**
* Creates a new instance of the AttestationClientBuilder class.
*/
public AttestationAdministrationClientBuilder() {
serviceVersion = AttestationServiceVersion.V2020_10_01;
tokenValidationOptions = new AttestationTokenValidationOptions();
httpLogOptions = new HttpLogOptions();
}
/**
* Builds an instance of AttestationClient sync client.
*
* Instantiating a synchronous Attestation client:
*
*
*
* AttestationAdministrationClient client = new AttestationAdministrationClientBuilder()
* .endpoint(endpoint)
* .credential(new DefaultAzureCredentialBuilder().build())
* .buildClient();
*
*
* @return an instance of {@link AttestationClient}.
* @throws IllegalStateException If both {@link #retryOptions(RetryOptions)}
* and {@link #retryPolicy(RetryPolicy)} have been set.
*/
public AttestationAdministrationClient buildClient() {
return new AttestationAdministrationClient(buildAsyncClient());
}
/**
* Builds an instance of AttestationAsyncClient async client.
*
* Instantiating a synchronous Attestation client:
*
*
*
* AttestationAdministrationAsyncClient asyncClient = new AttestationAdministrationClientBuilder()
* .endpoint(endpoint)
* .credential(new DefaultAzureCredentialBuilder().build())
* .buildAsyncClient();
*
*
* @return an instance of {@link AttestationClient}.
* @throws IllegalStateException If both {@link #retryOptions(RetryOptions)}
* and {@link #retryPolicy(RetryPolicy)} have been set.
*/
public AttestationAdministrationAsyncClient buildAsyncClient() {
return new AttestationAdministrationAsyncClient(buildInnerClient(), this.tokenValidationOptions);
}
/**
* Sets The attestation endpoint URI, for example https://mytenant.attest.azure.net.
*
* @param endpoint The endpoint to connect to.
* @return the AttestationClientBuilder.
*/
@Override
public AttestationAdministrationClientBuilder endpoint(String endpoint) {
Objects.requireNonNull(endpoint);
try {
new URL(endpoint);
} catch (MalformedURLException ex) {
throw logger.logExceptionAsError(new IllegalArgumentException(ex));
}
this.endpoint = endpoint;
return this;
}
/**
* Sets the desired API version for this attestation client.
* @param serviceVersion Specifies the API version to use in the outgoing API calls.
* @return the AttestationClientBuilder.
*/
public AttestationAdministrationClientBuilder serviceVersion(AttestationServiceVersion serviceVersion) {
Objects.requireNonNull(serviceVersion);
this.serviceVersion = serviceVersion;
return this;
}
/**
* Sets the {@link TokenCredential} used to authorize requests sent to the service. Refer to the Azure SDK for Java
* identity and authentication
* documentation for more details on proper usage of the {@link TokenCredential} type.
*
* @param credential {@link TokenCredential} used to authorize requests sent to the service.
* @return the AttestationClientBuilder.
*/
@Override
public AttestationAdministrationClientBuilder credential(TokenCredential credential) {
Objects.requireNonNull(credential);
this.tokenCredential = credential;
return this;
}
/**
* Sets the {@link HttpPipeline} to use for the service client.
*
* Note: It is important to understand the precedence order of the HttpTrait APIs. In
* particular, if a {@link HttpPipeline} is specified, this takes precedence over all other APIs in the trait, and
* they will be ignored. If no {@link HttpPipeline} is specified, a HTTP pipeline will be constructed internally
* based on the settings provided to this trait. Additionally, there may be other APIs in types that implement this
* trait that are also ignored if an {@link HttpPipeline} is specified, so please be sure to refer to the
* documentation of types that implement this trait to understand the full set of implications.
*
* @param pipeline {@link HttpPipeline} to use for sending service requests and receiving responses.
* @return the AttestationClientBuilder.
*/
@Override
public AttestationAdministrationClientBuilder pipeline(HttpPipeline pipeline) {
this.pipeline = pipeline;
return this;
}
/**
* Sets the {@link HttpClient} to use for sending and receiving requests to and from the service.
*
* Note: It is important to understand the precedence order of the HttpTrait APIs. In
* particular, if a {@link HttpPipeline} is specified, this takes precedence over all other APIs in the trait, and
* they will be ignored. If no {@link HttpPipeline} is specified, a HTTP pipeline will be constructed internally
* based on the settings provided to this trait. Additionally, there may be other APIs in types that implement this
* trait that are also ignored if an {@link HttpPipeline} is specified, so please be sure to refer to the
* documentation of types that implement this trait to understand the full set of implications.
*
* @param httpClient The {@link HttpClient} to use for requests.
* @return the AttestationClientBuilder.
*/
@Override
public AttestationAdministrationClientBuilder httpClient(HttpClient httpClient) {
this.httpClient = httpClient;
return this;
}
/**
* Sets the client-specific configuration used to retrieve client or global configuration properties
* when building a client.
*
* @param configuration Configuration store used to retrieve client configurations.
* @return the AttestationClientBuilder.
*/
@Override
public AttestationAdministrationClientBuilder configuration(Configuration configuration) {
this.configuration = configuration;
return this;
}
/**
* Sets the {@link HttpLogOptions logging configuration} to use when sending and receiving requests to and from
* the service. If a {@code logLevel} is not provided, default value of {@link HttpLogDetailLevel#NONE} is set.
*
* Note: It is important to understand the precedence order of the HttpTrait APIs. In
* particular, if a {@link HttpPipeline} is specified, this takes precedence over all other APIs in the trait, and
* they will be ignored. If no {@link HttpPipeline} is specified, a HTTP pipeline will be constructed internally
* based on the settings provided to this trait. Additionally, there may be other APIs in types that implement this
* trait that are also ignored if an {@link HttpPipeline} is specified, so please be sure to refer to the
* documentation of types that implement this trait to understand the full set of implications.
*
* @param httpLogOptions The {@link HttpLogOptions logging configuration} to use when sending and receiving requests
* to and from the service.
* @return the AttestationClientBuilder.
*/
@Override
public AttestationAdministrationClientBuilder httpLogOptions(HttpLogOptions httpLogOptions) {
this.httpLogOptions = httpLogOptions;
return this;
}
/**
* Sets The retry policy that will attempt to retry failed requests, if applicable.
*
*
* Setting this is mutually exclusive with using {@link #retryOptions(RetryOptions)}.
*
* @param retryPolicy the retryPolicy value.
* @return the AttestationClientBuilder.
*/
public AttestationAdministrationClientBuilder retryPolicy(RetryPolicy retryPolicy) {
this.retryPolicy = retryPolicy;
return this;
}
/**
* Sets the {@link RetryOptions} for all the requests made through the client.
*
*
Note: It is important to understand the precedence order of the HttpTrait APIs. In
* particular, if a {@link HttpPipeline} is specified, this takes precedence over all other APIs in the trait, and
* they will be ignored. If no {@link HttpPipeline} is specified, a HTTP pipeline will be constructed internally
* based on the settings provided to this trait. Additionally, there may be other APIs in types that implement this
* trait that are also ignored if an {@link HttpPipeline} is specified, so please be sure to refer to the
* documentation of types that implement this trait to understand the full set of implications.
*
* Setting this is mutually exclusive with using {@link #retryPolicy(RetryPolicy)}.
*
* @param retryOptions The {@link RetryOptions} to use for all the requests made through the client.
* @return the AttestationAdministrationClientBuilder.
*/
@Override
public AttestationAdministrationClientBuilder retryOptions(RetryOptions retryOptions) {
this.retryOptions = retryOptions;
return this;
}
/**
* Allows for setting common properties such as application ID, headers, proxy configuration, etc. Note that it is
* recommended that this method be called with an instance of the {@link HttpClientOptions}
* class (a subclass of the {@link ClientOptions} base class). The HttpClientOptions subclass provides more
* configuration options suitable for HTTP clients, which is applicable for any class that implements this HttpTrait
* interface.
*
*
Note: It is important to understand the precedence order of the HttpTrait APIs. In
* particular, if a {@link HttpPipeline} is specified, this takes precedence over all other APIs in the trait, and
* they will be ignored. If no {@link HttpPipeline} is specified, a HTTP pipeline will be constructed internally
* based on the settings provided to this trait. Additionally, there may be other APIs in types that implement this
* trait that are also ignored if an {@link HttpPipeline} is specified, so please be sure to refer to the
* documentation of types that implement this trait to understand the full set of implications.
*
* @param clientOptions A configured instance of {@link HttpClientOptions}.
* @return the updated {@link AttestationAdministrationClientBuilder} object
* @see HttpClientOptions
*/
@Override
public AttestationAdministrationClientBuilder clientOptions(ClientOptions clientOptions) {
this.clientOptions = clientOptions;
return this;
}
/**
* Adds a {@link HttpPipelinePolicy pipeline policy} to apply on each request sent.
*
* Note: It is important to understand the precedence order of the HttpTrait APIs. In
* particular, if a {@link HttpPipeline} is specified, this takes precedence over all other APIs in the trait, and
* they will be ignored. If no {@link HttpPipeline} is specified, a HTTP pipeline will be constructed internally
* based on the settings provided to this trait. Additionally, there may be other APIs in types that implement this
* trait that are also ignored if an {@link HttpPipeline} is specified, so please be sure to refer to the
* documentation of types that implement this trait to understand the full set of implications.
*
* @param policy A {@link HttpPipelinePolicy pipeline policy}.
* @return this {@link AttestationAdministrationClientBuilder}.
* @throws NullPointerException If {@code pipelinePolicy} is {@code null}.
*/
@Override
public AttestationAdministrationClientBuilder addPolicy(HttpPipelinePolicy policy) {
Objects.requireNonNull(policy, "'policy' cannot be null.");
if (policy.getPipelinePosition() == HttpPipelinePosition.PER_CALL) {
perCallPolicies.add(policy);
} else {
perRetryPolicies.add(policy);
}
return this;
}
/**
* Sets {@link com.azure.security.attestation.models.AttestationToken} validation options for clients created from this builder.
* Because attestation service clients need to have the ability to validate that the data returned by the attestation
* service actually originated from within the service, most Attestation Service APIs embed their response in a
* RFC 7519 JSON Web Token.
* The {@link AttestationTokenValidationOptions} provides a mechanism for a client to customize the validation
* of responses sent by the attestation service.
* The {@code tokenValidationOptions} property sets the default validation options used by the {@link AttestationClient}
* or {@link AttestationAsyncClient} returned from this builder.
* Note: most APIs allow this value to be overridden on a per-api basis if that flexibility is needed.
*
*
*
* AttestationAdministrationClient validatedClient = new AttestationAdministrationClientBuilder()
* .endpoint(endpoint)
* .tokenValidationOptions(new AttestationTokenValidationOptions()
* // Allow 10 seconds of clock drift between attestation service and client.
* .setValidationSlack(Duration.ofSeconds(10))
* .setValidationCallback((token, signer) -> { // Perform custom validation steps.
* System.out.printf("Validate token signed by signer %s\n",
* signer.getCertificates().get(0).getSubjectDN().toString());
* }))
* .buildClient();
*
*
* @param tokenValidationOptions - Validation options used when validating JSON Web Tokens returned by the attestation service.
* @return this {@link AttestationAdministrationClientBuilder}
*/
public AttestationAdministrationClientBuilder
tokenValidationOptions(AttestationTokenValidationOptions tokenValidationOptions) {
this.tokenValidationOptions = tokenValidationOptions;
return this;
}
/**
* Builds an instance of AttestationClientImpl with the provided parameters.
*
* @return an instance of AttestationClientImpl.
*/
private AttestationClientImpl buildInnerClient() {
// Global Env configuration store
Configuration buildConfiguration
= (configuration == null) ? Configuration.getGlobalConfiguration() : configuration;
// Service version
AttestationServiceVersion version
= serviceVersion != null ? serviceVersion : AttestationServiceVersion.getLatest();
// endpoint cannot be null.
String endpoint = this.endpoint;
Objects.requireNonNull(endpoint, "'Endpoint' is required and can not be null.");
// If the customer provided a pipeline, use it, otherwise configure the pipeline based on the options
// which were provided.
HttpPipeline pipeline = this.pipeline;
if (pipeline == null) {
// Closest to API goes first, closest to wire goes last.
final List policies = new ArrayList<>();
policies.add(new UserAgentPolicy(getApplicationId(clientOptions, httpLogOptions), CLIENT_NAME,
CLIENT_VERSION, buildConfiguration));
policies.add(new RequestIdPolicy());
policies.add(new AddHeadersFromContextPolicy());
policies.addAll(perCallPolicies);
HttpPolicyProviders.addBeforeRetryPolicies(policies);
policies.add(ClientBuilderUtil.validateAndGetRetryPolicy(retryPolicy, retryOptions, DEFAULT_RETRY_POLICY));
policies.add(new AddDatePolicy());
// If we want an authenticated connection, add a bearer token policy.
if (tokenCredential != null) {
// User token based policy
policies.add(new BearerTokenAuthenticationPolicy(tokenCredential, dataplaneScope));
}
policies.addAll(perRetryPolicies);
if (clientOptions != null) {
List httpHeaderList = new ArrayList<>();
clientOptions.getHeaders()
.forEach(header -> httpHeaderList.add(new HttpHeader(header.getName(), header.getValue())));
policies.add(new AddHeadersPolicy(new HttpHeaders(httpHeaderList)));
}
HttpPolicyProviders.addAfterRetryPolicies(policies);
policies.add(new HttpLoggingPolicy(httpLogOptions));
// Create a new pipeline based on the policies and with the specified HTTP client.
pipeline = new HttpPipelineBuilder().policies(policies.toArray(new HttpPipelinePolicy[0]))
.httpClient(httpClient)
.build();
}
return new AttestationClientImpl(pipeline, JacksonAdapter.createDefaultSerializerAdapter(), endpoint,
version.getVersion());
}
}