/* * 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.config.xml; import com.amazonaws.services.elasticache.AmazonElastiCache; import com.amazonaws.services.elasticache.AmazonElastiCacheClient; 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.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.Mockito; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cloud.aws.cache.config.TestMemcacheServer; import org.springframework.cloud.aws.context.config.xml.GlobalBeanDefinitionUtils; import org.springframework.cloud.aws.core.config.AmazonWebserviceClientConfigurationUtils; import org.springframework.cloud.aws.core.env.ResourceIdResolver; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.ClassPathResource; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.Mockito.when; /** * @author Agim Emruli */ public class CacheBeanDefinitionParserTest { @Rule public ExpectedException expectedException = ExpectedException.none(); @Test public void parseInternal_cacheConfigWithExpiration_returnsConfiguredCacheThatRespectExpiration() throws Exception { //Arrange DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); //Register a mock object which will be used to replay service calls BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(Mockito.class); beanDefinitionBuilder.setFactoryMethod("mock"); beanDefinitionBuilder.addConstructorArgValue(AmazonElastiCache.class); beanFactory.registerBeanDefinition(AmazonWebserviceClientConfigurationUtils.getBeanName(AmazonElastiCacheClient.class.getName()), beanDefinitionBuilder.getBeanDefinition()); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); reader.loadBeanDefinitions(new ClassPathResource(getClass().getSimpleName() + "-cacheConfigWithExpiration.xml", getClass())); AmazonElastiCache client = beanFactory.getBean(AmazonWebserviceClientConfigurationUtils.getBeanName(AmazonElastiCacheClient.class.getName()), AmazonElastiCache.class); //Replay invocation that will be called DescribeCacheClustersRequest memcached = new DescribeCacheClustersRequest().withCacheClusterId("memcached"); memcached.setShowCacheNodeInfo(true); when(client.describeCacheClusters(memcached)).thenReturn( new DescribeCacheClustersResult().withCacheClusters( new CacheCluster().withCacheClusterId("memcached"). withConfigurationEndpoint(new Endpoint().withAddress("localhost").withPort(Integer.parseInt(System.getProperty("memcachedPort")))). withCacheClusterStatus("available").withEngine("memcached") ) ); //Act CacheManager cacheManager = beanFactory.getBean(CacheManager.class); Cache cache = cacheManager.getCache("memcached"); cache.put("foo", "bar"); Thread.sleep(2000); //Assert assertNotNull(cacheManager); assertNotNull(cache); assertNull(cache.get("foo")); } @Test public void parseInternal_customCache_returnsCacheManagerWithCustomCache() throws Exception { //Arrange ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-customCache.xml", getClass()); //Act CacheManager cacheManager = applicationContext.getBean(CacheManager.class); Cache cache = cacheManager.getCache("memc"); cache.put("foo", "bar"); cache.evict("foo"); //Assert assertNotNull(cacheManager); assertNotNull(cache); } @Test public void parseInternal_mixedCacheConfig_returnsBothCaches() throws Exception { //Arrange DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); //Register a mock object which will be used to replay service calls BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(Mockito.class); beanDefinitionBuilder.setFactoryMethod("mock"); beanDefinitionBuilder.addConstructorArgValue(AmazonElastiCache.class); beanFactory.registerBeanDefinition(AmazonWebserviceClientConfigurationUtils.getBeanName(AmazonElastiCacheClient.class.getName()), beanDefinitionBuilder.getBeanDefinition()); BeanDefinitionBuilder cacheBuilder = BeanDefinitionBuilder.rootBeanDefinition(Mockito.class); cacheBuilder.setFactoryMethod("mock"); cacheBuilder.addConstructorArgValue(AmazonElastiCache.class); beanFactory.registerBeanDefinition(AmazonWebserviceClientConfigurationUtils.getBeanName(AmazonElastiCacheClient.class.getName()), cacheBuilder.getBeanDefinition()); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); reader.loadBeanDefinitions(new ClassPathResource(getClass().getSimpleName() + "-mixedCacheConfig.xml", getClass())); AmazonElastiCache client = beanFactory.getBean(AmazonWebserviceClientConfigurationUtils.getBeanName(AmazonElastiCacheClient.class.getName()), AmazonElastiCache.class); //Replay invocation that will be called DescribeCacheClustersRequest memcached1 = new DescribeCacheClustersRequest().withCacheClusterId("memcached"); memcached1.setShowCacheNodeInfo(true); when(client.describeCacheClusters(memcached1)).thenReturn( new DescribeCacheClustersResult().withCacheClusters( new CacheCluster().withCacheClusterId("memcached"). withConfigurationEndpoint(new Endpoint().withAddress("localhost").withPort(Integer.parseInt(System.getProperty("memcachedPort")))). withCacheClusterStatus("available").withEngine("memcached") ) ); Cache cache = beanFactory.getBean("memc", Cache.class); when(cache.getName()).thenReturn("memc"); //Act CacheManager cacheManager = beanFactory.getBean(CacheManager.class); Cache memc = cacheManager.getCache("memc"); Cache memcached = cacheManager.getCache("memcached"); //Assert assertNotNull(cacheManager); assertNotNull(memcached); memc.put("foo", "bar"); memc.evict("foo"); memcached.put("foo", "bar"); memcached.evict("foo"); } @Test public void parseInternal_clusterCacheConfiguration_returnsConfiguredClusterCache() throws Exception { //Arrange DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); //Register a mock object which will be used to replay service calls BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(Mockito.class); beanDefinitionBuilder.setFactoryMethod("mock"); beanDefinitionBuilder.addConstructorArgValue(AmazonElastiCache.class); beanFactory.registerBeanDefinition(AmazonWebserviceClientConfigurationUtils.getBeanName(AmazonElastiCacheClient.class.getName()), beanDefinitionBuilder.getBeanDefinition()); //Load xml file XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); xmlBeanDefinitionReader.loadBeanDefinitions(new ClassPathResource(getClass().getSimpleName() + "-elastiCacheConfig.xml", getClass())); AmazonElastiCache client = beanFactory.getBean(AmazonWebserviceClientConfigurationUtils.getBeanName(AmazonElastiCacheClient.class.getName()), AmazonElastiCache.class); //Replay invocation that will be called DescribeCacheClustersRequest memcached = new DescribeCacheClustersRequest().withCacheClusterId("memcached"); memcached.setShowCacheNodeInfo(true); when(client.describeCacheClusters(memcached)).thenReturn( new DescribeCacheClustersResult().withCacheClusters( new CacheCluster().withCacheClusterId("memcached"). withConfigurationEndpoint(new Endpoint().withAddress("localhost").withPort(Integer.parseInt(System.getProperty("memcachedPort")))). withCacheClusterStatus("available").withEngine("memcached") ) ); //Act CacheManager cacheManager = beanFactory.getBean(CacheManager.class); Cache cache = cacheManager.getCache("memcached"); cache.put("foo", "bar"); cache.evict("foo"); //Assert assertNotNull(cacheManager); assertNotNull(cache); } @Test public void parseInternal_clusterCacheConfigurationWithLogicalName_returnsConfiguredClusterCacheWithPhysicalName() throws Exception { //Arrange DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); //Register a mock object which will be used to replay service calls BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(Mockito.class); beanDefinitionBuilder.setFactoryMethod("mock"); beanDefinitionBuilder.addConstructorArgValue(AmazonElastiCache.class); beanFactory.registerBeanDefinition(AmazonWebserviceClientConfigurationUtils.getBeanName(AmazonElastiCacheClient.class.getName()), beanDefinitionBuilder.getBeanDefinition()); BeanDefinitionBuilder resourceIdBuilder = BeanDefinitionBuilder.rootBeanDefinition(Mockito.class); resourceIdBuilder.setFactoryMethod("mock"); resourceIdBuilder.addConstructorArgValue(ResourceIdResolver.class); beanFactory.registerBeanDefinition(GlobalBeanDefinitionUtils.RESOURCE_ID_RESOLVER_BEAN_NAME, resourceIdBuilder.getBeanDefinition()); //Load xml file XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); xmlBeanDefinitionReader.loadBeanDefinitions(new ClassPathResource(getClass().getSimpleName() + "-elastiCacheConfigStackConfigured.xml", getClass())); AmazonElastiCache client = beanFactory.getBean(AmazonWebserviceClientConfigurationUtils.getBeanName(AmazonElastiCacheClient.class.getName()), AmazonElastiCache.class); ResourceIdResolver resourceIdResolver = beanFactory.getBean(GlobalBeanDefinitionUtils.RESOURCE_ID_RESOLVER_BEAN_NAME, ResourceIdResolver.class); when(resourceIdResolver.resolveToPhysicalResourceId("testMemcached")).thenReturn("memcached"); //Replay invocation that will be called DescribeCacheClustersRequest memcached = new DescribeCacheClustersRequest().withCacheClusterId("memcached"); memcached.setShowCacheNodeInfo(true); when(client.describeCacheClusters(memcached)).thenReturn( new DescribeCacheClustersResult().withCacheClusters( new CacheCluster().withCacheClusterId("memcached"). withConfigurationEndpoint(new Endpoint().withAddress("localhost").withPort(Integer.parseInt(System.getProperty("memcachedPort")))). withCacheClusterStatus("available").withEngine("memcached") ) ); //Act CacheManager cacheManager = beanFactory.getBean(CacheManager.class); Cache cache = cacheManager.getCache("testMemcached"); cache.put("foo", "bar"); cache.evict("foo"); //Assert assertNotNull(cacheManager); assertNotNull(cache); } @Test public void parseInternal_clusterCacheConfigurationWithRegion_returnsConfiguredClusterCacheWithRegion() throws Exception { //Arrange DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); //Load xml file XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); xmlBeanDefinitionReader.loadBeanDefinitions(new ClassPathResource(getClass().getSimpleName() + "-elastiCacheConfigRegionConfigured.xml", getClass())); //Act BeanDefinition beanDefinition = beanFactory.getBeanDefinition(AmazonWebserviceClientConfigurationUtils.getBeanName(AmazonElastiCacheClient.class.getName())); //Assert assertNotNull(beanDefinition); assertNotNull(beanDefinition.getPropertyValues().get("customRegion")); } @Test public void parseInternal_clusterCacheConfigurationWithCustomElastiCacheClient_returnsConfigurationWithCustomClient() throws Exception { //Arrange DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); //Load xml file XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); xmlBeanDefinitionReader.loadBeanDefinitions(new ClassPathResource(getClass().getSimpleName() + "-elastiCacheConfigWithCustomElastiCacheClient.xml", getClass())); AmazonElastiCache amazonElastiCacheMock = beanFactory.getBean("customClient", AmazonElastiCache.class); DescribeCacheClustersRequest memcached = new DescribeCacheClustersRequest().withCacheClusterId("memcached"); memcached.setShowCacheNodeInfo(true); when(amazonElastiCacheMock.describeCacheClusters(memcached)).thenReturn( new DescribeCacheClustersResult().withCacheClusters( new CacheCluster().withCacheClusterId("memcached"). withConfigurationEndpoint(new Endpoint().withAddress("localhost").withPort(Integer.parseInt(System.getProperty("memcachedPort")))). withCacheClusterStatus("available").withEngine("memcached") ) ); //Act CacheManager cacheManager = beanFactory.getBean(CacheManager.class); Cache cache = cacheManager.getCache("memcached"); cache.put("foo", "bar"); cache.evict("foo"); //Assert assertNotNull(cacheManager); assertNotNull(cache); } @BeforeClass public static void setupMemcachedServerAndClient() throws Exception { // Get next free port for the test server int availableTcpPort = TestMemcacheServer.startServer(); // Set the port as system property to easily fetch it in the Spring config System.setProperty("memcachedPort", String.valueOf(availableTcpPort)); } @AfterClass public static void tearDownMemcachedServerAndClient() throws Exception { TestMemcacheServer.stopServer(); System.clearProperty("memcachedPort"); } }