private RegionalClientSupplier clientFactory() { if (regionalClientSupplier_ != null) { return regionalClientSupplier_; } // Clone again; this MKP builder might be reused to build a second MKP with different creds. AWSKMSClientBuilder builder = templateBuilder_ != null ? cloneClientBuilder(templateBuilder_) : AWSKMSClientBuilder.standard(); ConcurrentHashMap<String, AWSKMS> clientCache = new ConcurrentHashMap<>(); snoopClientCache(clientCache); return region -> { AWSKMS kms = clientCache.get(region); if (kms != null) return kms; // We can't just use computeIfAbsent as we need to avoid leaking KMS clients if we're asked to decrypt // an EDK with a bogus region in its ARN. So we'll install a request handler to identify the first // successful call, and cache it when we see that. SuccessfulRequestCacher cacher = new SuccessfulRequestCacher(clientCache, region); ArrayList<RequestHandler2> handlers = new ArrayList<>(); if (builder.getRequestHandlers() != null) { handlers.addAll(builder.getRequestHandlers()); } handlers.add(cacher); kms = cloneClientBuilder(builder) .withRegion(region) .withRequestHandlers(handlers.toArray(new RequestHandler2[handlers.size()])) .build(); cacher.client_ = kms; return kms; }; }
private AWSKMSClientBuilder cloneClientBuilder(final AWSKMSClientBuilder builder) { // We need to copy all arguments out of the builder in case it's mutated later on. // Unfortunately AWSKMSClientBuilder doesn't support .clone() so we'll have to do it by hand. if (builder.getEndpoint() != null) { // We won't be able to set the region later if a custom endpoint is set. throw new IllegalArgumentException("Setting endpoint configuration is not compatible with passing a " + "builder to the KmsMasterKeyProvider. Use withCustomClientFactory" + " instead."); } final AWSKMSClientBuilder newBuilder = AWSKMSClient.builder(); newBuilder.setClientConfiguration(builder.getClientConfiguration()); newBuilder.setCredentials(builder.getCredentials()); newBuilder.setEndpointConfiguration(builder.getEndpoint()); newBuilder.setMetricsCollector(builder.getMetricsCollector()); if (builder.getRequestHandlers() != null) { newBuilder.setRequestHandlers(builder.getRequestHandlers().toArray(new RequestHandler2[0])); } return newBuilder; }