/* * 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.cache; import com.amazonaws.services.elasticache.AmazonElastiCache; import com.amazonaws.services.elasticache.model.CacheCluster; import com.amazonaws.services.elasticache.model.DescribeCacheClustersRequest; import com.amazonaws.services.elasticache.model.DescribeCacheClustersResult; import com.amazonaws.services.elasticache.model.Endpoint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.cache.Cache; import org.springframework.cloud.aws.core.env.ResourceIdResolver; import java.util.List; /** * @author Agim Emruli */ public class ElastiCacheFactoryBean extends AbstractFactoryBean<Cache> { private static final Logger LOGGER = LoggerFactory.getLogger(ElastiCacheFactoryBean.class); private final AmazonElastiCache amazonElastiCache; private final String cacheClusterId; private final ResourceIdResolver resourceIdResolver; private final List<? extends CacheFactory> cacheFactories; public ElastiCacheFactoryBean(AmazonElastiCache amazonElastiCache, String cacheClusterId, ResourceIdResolver resourceIdResolver, List<? extends CacheFactory> cacheFactories) { this.amazonElastiCache = amazonElastiCache; this.resourceIdResolver = resourceIdResolver; this.cacheClusterId = cacheClusterId; this.cacheFactories = cacheFactories; } public ElastiCacheFactoryBean(AmazonElastiCache amazonElastiCache, String cacheClusterId, List<CacheFactory> cacheFactories) { this(amazonElastiCache, cacheClusterId, null, cacheFactories); } @Override public Class<Cache> getObjectType() { return Cache.class; } @Override protected Cache createInstance() throws Exception { DescribeCacheClustersRequest describeCacheClustersRequest = new DescribeCacheClustersRequest().withCacheClusterId(getCacheClusterName()); describeCacheClustersRequest.setShowCacheNodeInfo(true); DescribeCacheClustersResult describeCacheClustersResult = this.amazonElastiCache.describeCacheClusters(describeCacheClustersRequest); CacheCluster cacheCluster = describeCacheClustersResult.getCacheClusters().get(0); if (!"available".equals(cacheCluster.getCacheClusterStatus())) { LOGGER.warn("Cache cluster is not available now. Connection may fail during cache access. Current status is {}", cacheCluster.getCacheClusterStatus()); } Endpoint configurationEndpoint = getEndpointForCache(cacheCluster); for (CacheFactory cacheFactory : this.cacheFactories) { if (cacheFactory.isSupportingCacheArchitecture(cacheCluster.getEngine())) { return cacheFactory.createCache(this.cacheClusterId, configurationEndpoint.getAddress(), configurationEndpoint.getPort()); } } throw new IllegalArgumentException("No CacheFactory configured for engine: " + cacheCluster.getEngine()); } @Override protected void destroyInstance(Cache instance) throws Exception { if (instance instanceof DisposableBean) { ((DisposableBean) instance).destroy(); } } private String getCacheClusterName() { return this.resourceIdResolver != null ? this.resourceIdResolver.resolveToPhysicalResourceId(this.cacheClusterId) : this.cacheClusterId; } private static Endpoint getEndpointForCache(CacheCluster cacheCluster) { if (cacheCluster.getConfigurationEndpoint() != null) { return cacheCluster.getConfigurationEndpoint(); } if (!cacheCluster.getCacheNodes().isEmpty()) { return cacheCluster.getCacheNodes().get(0).getEndpoint(); } throw new IllegalArgumentException("No Configuration Endpoint or Cache Node available to " + "receive address information for cluster:'" + cacheCluster.getCacheClusterId() + "'"); } }