Java tutorial
/* * Copyright 2016 Netflix, Inc. * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.netflix.spinnaker.clouddriver.aws.security.sdkclient; import com.amazonaws.client.builder.AwsClientBuilder; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; import com.netflix.spectator.api.Registry; import com.netflix.spinnaker.clouddriver.aws.security.EddaTemplater; import com.netflix.spinnaker.clouddriver.aws.security.EddaTimeoutConfig; import com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials; import org.apache.http.client.HttpClient; import java.lang.reflect.Proxy; import java.util.Map; import static java.util.Objects.requireNonNull; /** * Constructs a JDK dynamic proxy for an AWS service interface that (if enabled for an account) will * delegate read requests to Edda and otherwise fallback to the underlying SDK client. */ public class ProxyHandlerBuilder { private final AwsSdkClientSupplier awsSdkClientSupplier; private final HttpClient httpClient; private final ObjectMapper objectMapper; private final EddaTemplater eddaTemplater; private final EddaTimeoutConfig eddaTimeoutConfig; private final Registry registry; public ProxyHandlerBuilder(AwsSdkClientSupplier awsSdkClientSupplier, HttpClient httpClient, ObjectMapper objectMapper, EddaTemplater eddaTemplater, EddaTimeoutConfig eddaTimeoutConfig, Registry registry) { this.awsSdkClientSupplier = requireNonNull(awsSdkClientSupplier); this.httpClient = requireNonNull(httpClient); this.objectMapper = requireNonNull(objectMapper); this.eddaTemplater = requireNonNull(eddaTemplater); this.eddaTimeoutConfig = eddaTimeoutConfig; this.registry = requireNonNull(registry); } public <T extends AwsClientBuilder<T, U>, U> U getProxyHandler(Class<U> interfaceKlazz, Class<T> impl, NetflixAmazonCredentials amazonCredentials, String region) { return getProxyHandler(interfaceKlazz, impl, amazonCredentials, region, false); } public <T extends AwsClientBuilder<T, U>, U> U getProxyHandler(Class<U> interfaceKlazz, Class<T> impl, NetflixAmazonCredentials amazonCredentials, String region, boolean skipEdda) { requireNonNull(amazonCredentials, "Credentials cannot be null"); try { U delegate = awsSdkClientSupplier.getClient(impl, interfaceKlazz, amazonCredentials.getName(), amazonCredentials.getCredentialsProvider(), region); if (skipEdda || !amazonCredentials.getEddaEnabled() || eddaTimeoutConfig.getDisabledRegions().contains(region)) { return delegate; } return interfaceKlazz.cast(Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { interfaceKlazz }, getInvocationHandler(delegate, interfaceKlazz.getSimpleName(), region, amazonCredentials))); } catch (RuntimeException re) { throw re; } catch (Exception e) { throw new RuntimeException("Instantiation of client implementation failed!", e); } } protected AmazonClientInvocationHandler getInvocationHandler(Object client, String serviceName, String region, NetflixAmazonCredentials amazonCredentials) { final Map<String, String> baseTags = ImmutableMap.of("account", amazonCredentials.getName(), "region", region, "serviceName", serviceName); return new AmazonClientInvocationHandler(client, serviceName, eddaTemplater.getUrl(amazonCredentials.getEdda(), region), this.httpClient, objectMapper, eddaTimeoutConfig, registry, baseTags); } }