package org.distributeme.core.failing; import net.anotheria.moskito.core.producers.IStatsProducer; import net.anotheria.moskito.core.registry.ProducerRegistryFactory; import org.distributeme.core.ClientSideCallContext; import org.distributeme.core.exception.ServiceUnavailableException; import org.distributeme.core.routing.GenericRouterConfiguration; import org.distributeme.core.routing.blacklisting.BlacklistingStrategy; import org.distributeme.core.routing.blacklisting.ErrorsPerIntervalBlacklistingStrategy; import org.distributeme.core.routing.blacklisting.NoOpBlacklistingStrategy; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import java.util.Collection; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * Created by hpemoeller on 4/10/17. */ public class FailoverAndReturnWithConfigurableBlacklistingTest { public static final String FAILOVER_SUFFIX = "_failover"; private final String serviceId = "ServiceId"; private final String failoverServiceId = serviceId + FAILOVER_SUFFIX; private final GenericRouterConfiguration configuration = new GenericRouterConfiguration(); private final String configurationName = "blacklisting-routing-test-regular"; private final BlacklistingStrategy blacklistingStrategyMock = mock(BlacklistingStrategy.class); private FailoverAndReturnWithConfigurableBlacklisting router = new FailoverAndReturnWithConfigurableBlacklisting(); private final ClientSideCallContext clientSideCallContext = new ClientSideCallContext("ServiceId", "context", null); @Before public void setUp() throws Exception { ProducerRegistryFactory.getProducerRegistryInstance().cleanup(); router.setConfiguration(configuration); } @Test public void setServiceIdShouldRegisterAMoskitoProducer() throws Exception { router.setConfigurationName (serviceId, configurationName); Collection<IStatsProducer> producers = ProducerRegistryFactory.getProducerRegistryInstance().getProducers(); assertThat(producers.size(), is(1)); assertThat(producers.iterator().next().getProducerId(), is("_" +serviceId + "-Router")); } @Test public void setConfigurationNameShouldConfigureTheGenericRouterConfig() throws Exception { router.setConfigurationName(serviceId, configurationName); assertThat(configuration.getBlacklistTime(), is(20000l)); } @Test(expected = IllegalStateException.class) public void setConfigurationNameShouldThrowExceptionIfConfigurationFileDoesNotExist() throws Exception { router.setConfigurationName(serviceId, "NoExistingFileName"); } @Test public void getFailbackTimeoutShouldReturnConfiguredValue() { router.setConfigurationName(serviceId, configurationName); assertThat(router.getFailbackTimeout(), is(20000l)); } @Test public void routerConfigurationChangeShouldReplaceTheExsistionConfiguration() throws Exception { GenericRouterConfiguration configuration = new GenericRouterConfiguration(); configuration.setBlacklistTime(159l); router.routerConfigurationChange(configuration); assertThat(router.getFailbackTimeout(), is(159l)); } @Test public void theBlackListingStrategyShouldChangeOnAfterInitialConfiguration() throws Exception { // given router.setConfigurationName (serviceId, configurationName); assertThat(router.getBlacklistingStrategy(), instanceOf(NoOpBlacklistingStrategy.class)); // when router.getConfiguration().setBlacklistStrategyClazz("org.distributeme.core.routing.blacklisting.ErrorsPerIntervalBlacklistingStrategy"); router.getConfiguration().afterConfiguration(); // then assertThat(router.getBlacklistingStrategy(), instanceOf(ErrorsPerIntervalBlacklistingStrategy.class)); } @Test public void theBlackListingStrategyShouldChangeOnObserverCall() throws Exception { // given router.setConfigurationName (serviceId, configurationName); assertThat(router.getBlacklistingStrategy(), instanceOf(NoOpBlacklistingStrategy.class)); // when router.getConfiguration().setBlacklistStrategyClazz("org.distributeme.core.routing.blacklisting.ErrorsPerIntervalBlacklistingStrategy"); router.getConfiguration().afterReConfiguration(); // then assertThat(router.getBlacklistingStrategy(), instanceOf(ErrorsPerIntervalBlacklistingStrategy.class)); } @Test public void getSuffixShouldReturnTheRightSuffix(){ assertThat(router.getSuffix(), is(FAILOVER_SUFFIX)); } @Test public void callFailedShouldNotifyTheStrategy(){ router.setBlacklistingStrategy(blacklistingStrategyMock); router.callFailed(clientSideCallContext); verify(blacklistingStrategyMock).notifyCallFailed(clientSideCallContext); } @Test public void callFailedShouldAskIfNextServiceIsBlacklisted(){ router.setBlacklistingStrategy(blacklistingStrategyMock); router.callFailed(clientSideCallContext); verify(blacklistingStrategyMock).isBlacklisted(failoverServiceId); } @Test public void ifServiceIsBlacklistedRetryOneFailDecisionWithFailOverServiceIdShouldBeReturned() throws Exception { when(blacklistingStrategyMock.isBlacklisted(clientSideCallContext.getServiceId())).thenReturn(true); router.setBlacklistingStrategy(blacklistingStrategyMock); FailDecision result = router.callFailed(clientSideCallContext); assertThat(result.getReaction(), is(FailDecision.Reaction.RETRYONCE)); assertThat(result.getTargetService(), is("ServiceId" + FAILOVER_SUFFIX)); } @Test public void ifServiceIsNotBlacklistedRetryWithServiceIdShouldBeReturned(){ router.setBlacklistingStrategy(blacklistingStrategyMock); when(blacklistingStrategyMock.isBlacklisted(clientSideCallContext.getServiceId())).thenReturn(false); FailDecision result = router.callFailed(clientSideCallContext); assertThat(result.getReaction(), is(FailDecision.Reaction.RETRYONCE)); assertThat(result.getTargetService(), is(failoverServiceId)); } @Test(expected = ServiceUnavailableException.class) public void ifBothServicesAreBlackListedAnExceptionShouldBeThrown(){ router.setBlacklistingStrategy(blacklistingStrategyMock); when(blacklistingStrategyMock.isBlacklisted(clientSideCallContext.getServiceId())).thenReturn(true); when(blacklistingStrategyMock.isBlacklisted(clientSideCallContext.getServiceId() + FAILOVER_SUFFIX)).thenReturn(true); router.callFailed(clientSideCallContext); } @Test public void ifCallFailedGetsFailsWithFailOverInstanceItShouldFallBackToTheNormalInstance(){ clientSideCallContext.setServiceId(failoverServiceId); router.setBlacklistingStrategy(blacklistingStrategyMock); when(blacklistingStrategyMock.isBlacklisted(failoverServiceId)).thenReturn(true); when(blacklistingStrategyMock.isBlacklisted(serviceId)).thenReturn(false); FailDecision result = router.callFailed(clientSideCallContext); assertThat(result.getReaction(), is(FailDecision.Reaction.RETRYONCE)); assertThat(result.getTargetService(), is("ServiceId" )); } @Test(expected = ServiceUnavailableException.class) public void ifCallFailedGetsFailsWithFailOverInstanceAndTheNormalInstanceIsBlacklistedAnExceptionShouldBeThrown(){ clientSideCallContext.setServiceId(failoverServiceId); router.setBlacklistingStrategy(blacklistingStrategyMock); when(blacklistingStrategyMock.isBlacklisted(failoverServiceId)).thenReturn(true); when(blacklistingStrategyMock.isBlacklisted(serviceId)).thenReturn(true); router.callFailed(clientSideCallContext); } @Test public void ifBothServicesAreBlackListedAnd_isOverrideBlacklistIfAllBlacklisted_isTrueTheOtherShouldBeCalled(){ router.getConfiguration().setOverrideBlacklistIfAllBlacklisted(true); router.setBlacklistingStrategy(blacklistingStrategyMock); when(blacklistingStrategyMock.isBlacklisted(clientSideCallContext.getServiceId())).thenReturn(true); when(blacklistingStrategyMock.isBlacklisted(clientSideCallContext.getServiceId() + FAILOVER_SUFFIX)).thenReturn(true); FailDecision result = router.callFailed(clientSideCallContext); assertThat(result.getReaction(), is(FailDecision.Reaction.RETRYONCE)); assertThat(result.getTargetService(), is(failoverServiceId )); } @Test public void getServiceIdForCallShouldReturnTheNormalInstance(){ String result = router.getServiceIdForCall(clientSideCallContext); assertThat(result, is(serviceId)); } @Test public void getServiceIdForCallShouldReturnTheFailoverInstanceIfServiceIsBlackListed(){ when(blacklistingStrategyMock.isBlacklisted(serviceId)).thenReturn(true); router.setBlacklistingStrategy(blacklistingStrategyMock); String result = router.getServiceIdForCall(clientSideCallContext); assertThat(result, is(failoverServiceId)); } }