com.netflix.spinnaker.clouddriver.aws.security.sdkclient.ProxyHandlerBuilder.java Source code

Java tutorial

Introduction

Here is the source code for com.netflix.spinnaker.clouddriver.aws.security.sdkclient.ProxyHandlerBuilder.java

Source

/*
 * 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);
    }

}