/** * diqube: Distributed Query Base. * * Copyright (C) 2015 Bastian Gloeckle * * This file is part of diqube. * * diqube is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.diqube.consensus.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import javax.inject.Inject; import org.diqube.consensus.ConsensusClient; import org.diqube.context.AutoInstatiate; import org.diqube.context.Profiles; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Profile; /** * Implementation of {@link ConsensusClient} for unit tests: Forwards method calls to the {@link ConsensusClient} to * locally instantiated beans, without actually running a consensus cluster. * * @author Bastian Gloeckle */ @AutoInstatiate @Profile(Profiles.TEST_CONSENSUS) public class TestConsensusClient implements ConsensusClient { @Inject private ApplicationContext context; @Override public <T> ClosableProvider<T> getStateMachineClient(Class<T> stateMachineInterface) throws IllegalStateException { T serviceBean = context.getBean(stateMachineInterface); if (serviceBean == null) throw new IllegalStateException("Bean not found for " + stateMachineInterface); InvocationHandler h = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Method beanMethod = serviceBean.getClass().getMethod(method.getName(), method.getParameterTypes()); if (beanMethod == null) throw new RuntimeException("Method " + method.getName() + " not found on " + serviceBean); return beanMethod.invoke(serviceBean, args); } }; @SuppressWarnings("unchecked") T stateMachineProxy = (T) Proxy.newProxyInstance(TestConsensusClient.class.getClassLoader(), new Class<?>[] { stateMachineInterface }, h); return new ClosableProvider<T>() { @Override public void close() { // noop. } @Override public T getClient() { return stateMachineProxy; } }; } @Override public void contextAboutToShutdown() { // noop } }