/*
* Copyright 2016-2017 Groupon, Inc
* Copyright 2016-2017 The Billing Project, LLC
*
* The Billing Project licenses this file to you 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.killbill.billing.payment.caching;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import org.killbill.automaton.StateMachineConfig;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.payment.PaymentTestSuiteNoDB;
import org.killbill.billing.tenant.api.TenantKV.TenantKey;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class TestStateMachineConfigCacheInvalidationCallback extends PaymentTestSuiteNoDB {
private InternalTenantContext multiTenantContext;
private InternalTenantContext otherMultiTenantContext;
@BeforeMethod(groups = "fast")
public void beforeMethod() throws Exception {
super.beforeMethod();
cacheControllerDispatcher.clearAll();
multiTenantContext = Mockito.mock(InternalTenantContext.class);
Mockito.when(multiTenantContext.getAccountRecordId()).thenReturn(456L);
Mockito.when(multiTenantContext.getTenantRecordId()).thenReturn(99L);
otherMultiTenantContext = Mockito.mock(InternalCallContext.class);
Mockito.when(otherMultiTenantContext.getAccountRecordId()).thenReturn(123L);
Mockito.when(otherMultiTenantContext.getTenantRecordId()).thenReturn(112233L);
}
@Test(groups = "fast")
public void testInvalidation() throws Exception {
final String pluginName = UUID.randomUUID().toString();
final StateMachineConfig defaultPaymentStateMachineConfig = stateMachineConfigCache.getPaymentStateMachineConfig(UUID.randomUUID().toString(), internalCallContext);
Assert.assertNotNull(defaultPaymentStateMachineConfig);
final AtomicBoolean shouldThrow = new AtomicBoolean(false);
Mockito.when(tenantInternalApi.getPluginPaymentStateMachineConfig(Mockito.eq(pluginName), Mockito.any(InternalTenantContext.class))).thenAnswer(new Answer<String>() {
@Override
public String answer(final InvocationOnMock invocation) throws Throwable {
if (shouldThrow.get()) {
throw new RuntimeException("For test purposes");
}
return null;
}
});
// Prime caches
Assert.assertEquals(stateMachineConfigCache.getPaymentStateMachineConfig(pluginName, internalCallContext), defaultPaymentStateMachineConfig);
Assert.assertEquals(stateMachineConfigCache.getPaymentStateMachineConfig(pluginName, otherMultiTenantContext), defaultPaymentStateMachineConfig);
shouldThrow.set(true);
// No exception (cached)
Assert.assertEquals(stateMachineConfigCache.getPaymentStateMachineConfig(pluginName, internalCallContext), defaultPaymentStateMachineConfig);
cacheInvalidationCallback.invalidateCache(TenantKey.PLUGIN_PAYMENT_STATE_MACHINE_, pluginName, multiTenantContext);
try {
stateMachineConfigCache.getPaymentStateMachineConfig(pluginName, multiTenantContext);
Assert.fail();
} catch (final RuntimeException exception) {
Assert.assertTrue(exception.getCause() instanceof RuntimeException);
Assert.assertEquals(exception.getCause().getMessage(), "For test purposes");
}
// No exception (cached)
Assert.assertEquals(stateMachineConfigCache.getPaymentStateMachineConfig(pluginName, otherMultiTenantContext), defaultPaymentStateMachineConfig);
}
}