/**
* 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.hystrix.contrib.javanica.test.common.command;
import com.netflix.hystrix.HystrixEventType;
import com.netflix.hystrix.HystrixInvokableInfo;
import com.netflix.hystrix.HystrixRequestLog;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.command.AsyncResult;
import com.netflix.hystrix.contrib.javanica.test.common.BasicHystrixTest;
import com.netflix.hystrix.contrib.javanica.test.common.domain.User;
import org.junit.Before;
import org.junit.Test;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public abstract class BasicCommandTest extends BasicHystrixTest {
private UserService userService;
private AdvancedUserService advancedUserService;
private GenericService<String, Long, User> genericUserService;
@Before
public void setUp() throws Exception {
userService = createUserService();
advancedUserService = createAdvancedUserServiceService();
genericUserService = createGenericUserService();
}
@Test
public void testGetUserAsync() throws ExecutionException, InterruptedException {
Future<User> f1 = userService.getUserAsync("1", "name: ");
assertEquals("name: 1", f1.get().getName());
assertEquals(1, HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().size());
com.netflix.hystrix.HystrixInvokableInfo<?> command = getCommand();
// assert the command key name is the we're expecting
assertEquals("GetUserCommand", command.getCommandKey().name());
// assert the command group key name is the we're expecting
assertEquals("UserService", command.getCommandGroup().name());
// assert the command thread pool key name is the we're expecting
assertEquals("CommandTestAsync", command.getThreadPoolKey().name());
// it was successful
assertTrue(command.getExecutionEvents().contains(HystrixEventType.SUCCESS));
}
@Test
public void testGetUserSync() {
User u1 = userService.getUserSync("1", "name: ");
assertGetUserSnycCommandExecuted(u1);
}
@Test
public void shouldWorkWithInheritedMethod() {
User u1 = advancedUserService.getUserSync("1", "name: ");
assertGetUserSnycCommandExecuted(u1);
}
@Test
public void should_work_with_parameterized_method() throws Exception {
assertEquals(Integer.valueOf(1), userService.echo(1));
assertEquals(1, HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().size());
assertTrue(getCommand().getExecutionEvents().contains(HystrixEventType.SUCCESS));
}
@Test
public void should_work_with_parameterized_asyncMethod() throws Exception {
assertEquals(Integer.valueOf(1), userService.echoAsync(1).get());
assertEquals(1, HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().size());
assertTrue(getCommand().getExecutionEvents().contains(HystrixEventType.SUCCESS));
}
@Test
public void should_work_with_genericClass_fallback() {
User user = genericUserService.getByKeyForceFail("1", 2L);
assertEquals("name: 2", user.getName());
assertEquals(1, HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().size());
HystrixInvokableInfo<?> command = HystrixRequestLog.getCurrentRequest()
.getAllExecutedCommands().iterator().next();
assertEquals("getByKeyForceFail", command.getCommandKey().name());
// confirm that command has failed
assertTrue(command.getExecutionEvents().contains(HystrixEventType.FAILURE));
// and that fallback was successful
assertTrue(command.getExecutionEvents().contains(HystrixEventType.FALLBACK_SUCCESS));
}
private void assertGetUserSnycCommandExecuted(User u1) {
assertEquals("name: 1", u1.getName());
assertEquals(1, HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().size());
com.netflix.hystrix.HystrixInvokableInfo<?> command = getCommand();
assertEquals("getUserSync", command.getCommandKey().name());
assertEquals("UserGroup", command.getCommandGroup().name());
assertEquals("UserGroup", command.getThreadPoolKey().name());
assertTrue(command.getExecutionEvents().contains(HystrixEventType.SUCCESS));
}
private com.netflix.hystrix.HystrixInvokableInfo<?> getCommand() {
return HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().iterator().next();
}
protected abstract UserService createUserService();
protected abstract AdvancedUserService createAdvancedUserServiceService();
protected abstract GenericService<String, Long, User> createGenericUserService();
public interface GenericService<K1, K2, V> {
V getByKey(K1 key1, K2 key2);
V getByKeyForceFail(K1 key, K2 key2);
V fallback(K1 key, K2 key2);
}
public static class GenericUserService implements GenericService<String, Long, User> {
@HystrixCommand(fallbackMethod = "fallback")
@Override
public User getByKey(String sKey, Long lKey) {
return new User(sKey, "name: " + lKey); // it should be network call
}
@HystrixCommand(fallbackMethod = "fallback")
@Override
public User getByKeyForceFail(String sKey, Long lKey) {
throw new RuntimeException("force fail");
}
@Override
public User fallback(String sKey, Long lKey) {
return new User(sKey, "name: " + lKey);
}
}
public static class UserService {
@HystrixCommand(commandKey = "GetUserCommand", threadPoolKey = "CommandTestAsync")
public Future<User> getUserAsync(final String id, final String name) {
return new AsyncResult<User>() {
@Override
public User invoke() {
return new User(id, name + id); // it should be network call
}
};
}
@HystrixCommand(groupKey = "UserGroup")
public User getUserSync(String id, String name) {
return new User(id, name + id); // it should be network call
}
@HystrixCommand
public <T> T echo(T value) {
return value;
}
@HystrixCommand
public <T> Future<T> echoAsync(final T value) {
return new AsyncResult<T>() {
@Override
public T invoke() {
return value;
}
};
}
}
public static class AdvancedUserService extends UserService {
}
}