/* * Copyright 2013-2014 the original author or authors. * * 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 org.springframework.cloud.aws.core.config; import com.amazonaws.AmazonWebServiceClient; import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.client.builder.AwsAsyncClientBuilder; import com.amazonaws.client.builder.AwsClientBuilder; import com.amazonaws.client.builder.ExecutorFactory; import com.amazonaws.regions.Region; import com.amazonaws.regions.RegionUtils; import com.amazonaws.regions.Regions; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.cloud.aws.core.region.RegionProvider; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; import java.lang.reflect.Method; import java.util.concurrent.ExecutorService; /** * {@link org.springframework.beans.factory.FactoryBean} class to create {@link AmazonWebServiceClient} instances. This class * is responsible to create the respective AmazonWebServiceClient classes because the configuration through Springs's * BeanFactory fails due to invalid properties inside the Webservice client classes (see * https://github.com/aws/aws-sdk-java/issues/325) * * @author Agim Emruli */ public class AmazonWebserviceClientFactoryBean<T extends AmazonWebServiceClient> extends AbstractFactoryBean<T> { private final Class<? extends AmazonWebServiceClient> clientClass; private final AWSCredentialsProvider credentialsProvider; private RegionProvider regionProvider; private Region customRegion; private ExecutorService executor; public AmazonWebserviceClientFactoryBean(Class<T> clientClass, AWSCredentialsProvider credentialsProvider) { this.clientClass = clientClass; this.credentialsProvider = credentialsProvider; } public AmazonWebserviceClientFactoryBean(Class<T> clientClass, AWSCredentialsProvider credentialsProvider, RegionProvider regionProvider) { this(clientClass, credentialsProvider); setRegionProvider(regionProvider); } @Override public Class<?> getObjectType() { return this.clientClass; } @SuppressWarnings("unchecked") @Override protected T createInstance() throws Exception { String builderName = this.clientClass.getName() + "Builder"; Class<?> className = ClassUtils.resolveClassName(builderName, ClassUtils.getDefaultClassLoader()); Method method = ClassUtils.getStaticMethod(className, "standard"); Assert.notNull(method, "Could not find standard() method in class:'" + className.getName() + "'"); AwsClientBuilder<?, T> builder = (AwsClientBuilder<?, T>) ReflectionUtils.invokeMethod(method, null); if (this.executor != null) { AwsAsyncClientBuilder<?, T> asyncBuilder = (AwsAsyncClientBuilder<?, T>) builder; asyncBuilder.withExecutorFactory(new ExecutorFactory() { @Override public ExecutorService newExecutor() { return AmazonWebserviceClientFactoryBean.this.executor; } }); } if (this.credentialsProvider != null) { builder.withCredentials(this.credentialsProvider); } if (this.customRegion != null) { builder.withRegion(this.customRegion.getName()); } else if (this.regionProvider != null) { builder.withRegion(this.regionProvider.getRegion().getName()); } else { builder.withRegion(Regions.DEFAULT_REGION); } return builder.build(); } public void setRegionProvider(RegionProvider regionProvider) { this.regionProvider = regionProvider; } public void setCustomRegion(String customRegionName) { this.customRegion = RegionUtils.getRegion(customRegionName); } public void setExecutor(ExecutorService executor) { this.executor = executor; } @Override protected void destroyInstance(T instance) throws Exception { instance.shutdown(); } }