/** * Copyright 2015 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.hystrix.contrib.javanica.cache; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey; import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheRemove; import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult; import com.netflix.hystrix.contrib.javanica.command.MetaHolder; import com.netflix.hystrix.contrib.javanica.exception.HystrixCachingException; import org.junit.Test; import java.lang.annotation.Annotation; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; /** * Unit test for {@link CacheInvocationContextFactory}. * * @author dmgcodevil */ public class CacheInvocationContextFactoryTest { @Test public void testCreateCacheResultInvocationContext_givenMethodAnnotatedWithCacheResult_shouldCreateCorrectCacheKeyInvocationContext() throws NoSuchMethodException { // given TestCacheClass testCacheClass = new TestCacheClass(); String param1 = "val_1"; String param2 = "val_2"; Integer param3 = 3; MetaHolder metaHolder = MetaHolder.builder() .method(TestCacheClass.class.getMethod("cacheResultMethod", String.class, String.class, Integer.class)) .args(new Object[]{param1, param2, param3}) .obj(testCacheClass).build(); // when CacheInvocationContext<CacheResult> context = CacheInvocationContextFactory.createCacheResultInvocationContext(metaHolder); // then assertNotNull(context.getKeyParameters()); assertEquals(2, context.getKeyParameters().size()); assertEquals(String.class, context.getKeyParameters().get(0).getRawType()); assertEquals(0, context.getKeyParameters().get(0).getPosition()); assertEquals(param1, context.getKeyParameters().get(0).getValue()); assertTrue(isAnnotationPresent(context.getKeyParameters().get(0), CacheKey.class)); assertEquals(Integer.class, context.getKeyParameters().get(1).getRawType()); assertEquals(2, context.getKeyParameters().get(1).getPosition()); assertEquals(param3, context.getKeyParameters().get(1).getValue()); assertTrue(isAnnotationPresent(context.getKeyParameters().get(1), CacheKey.class)); } @Test public void testCreateCacheRemoveInvocationContext_givenMethodAnnotatedWithCacheRemove_shouldCreateCorrectCacheKeyInvocationContext() throws NoSuchMethodException { // given TestCacheClass testCacheClass = new TestCacheClass(); String param1 = "val_1"; MetaHolder metaHolder = MetaHolder.builder() .method(TestCacheClass.class.getMethod("cacheRemoveMethod", String.class)) .args(new Object[]{param1}) .obj(testCacheClass).build(); // when CacheInvocationContext<CacheRemove> context = CacheInvocationContextFactory.createCacheRemoveInvocationContext(metaHolder); // then assertNotNull(context.getKeyParameters()); assertEquals(1, context.getKeyParameters().size()); CacheInvocationParameter actual = context.getKeyParameters().get(0); assertEquals(String.class, actual.getRawType()); assertEquals(param1, actual.getValue()); assertEquals(0, actual.getPosition()); } @Test(expected = HystrixCachingException.class) public void testCacheResultMethodWithWrongCacheKeyMethodSignature_givenWrongCacheKeyMethod_shouldThrowException() throws NoSuchMethodException { // given TestCacheClass testCacheClass = new TestCacheClass(); String param1 = "val_1"; MetaHolder metaHolder = MetaHolder.builder() .method(TestCacheClass.class.getMethod("cacheResultMethodWithWrongCacheKeyMethodSignature", String.class)) .args(new Object[]{param1}) .obj(testCacheClass).build(); // when CacheInvocationContext<CacheResult> context = CacheInvocationContextFactory.createCacheResultInvocationContext(metaHolder); // then expected HystrixCachingException } @Test(expected = HystrixCachingException.class) public void testCacheResultMethodWithCacheKeyMethodWithWrongReturnType_givenCacheKeyMethodWithWrongReturnType_shouldThrowException() throws NoSuchMethodException { // given TestCacheClass testCacheClass = new TestCacheClass(); String param1 = "val_1"; MetaHolder metaHolder = MetaHolder.builder() .method(TestCacheClass.class.getMethod("cacheResultMethodWithCacheKeyMethodWithWrongReturnType", String.class, String.class)) .args(new Object[]{param1}) .obj(testCacheClass).build(); // when CacheInvocationContext<CacheResult> context = CacheInvocationContextFactory.createCacheResultInvocationContext(metaHolder); System.out.println(context); // then expected HystrixCachingException } public static class TestCacheClass { @CacheResult public Object cacheResultMethod(@CacheKey String param1, String param2, @CacheKey Integer param3) { return null; } @CacheRemove(commandKey = "test") public Object cacheRemoveMethod(String param1) { return null; } @CacheResult(cacheKeyMethod = "cacheKeyMethodSignature") public Object cacheResultMethodWithWrongCacheKeyMethodSignature(String param2) { return null; } private String cacheKeyMethodSignature(String param1, String param2) { return null; } @CacheResult(cacheKeyMethod = "cacheKeyMethodWithWrongReturnType") public Object cacheResultMethodWithCacheKeyMethodWithWrongReturnType(String param1, String param2) { return null; } private Long cacheKeyMethodWithWrongReturnType(String param1, String param2) { return null; } } private static boolean isAnnotationPresent(CacheInvocationParameter parameter, final Class<?> annotation) { return Iterables.tryFind(parameter.getAnnotations(), new Predicate<Annotation>() { @Override public boolean apply(Annotation input) { return input.annotationType().equals(annotation); } }).isPresent(); } }