/*
* Copyright 2010-2013 the original author or authors.
*
* 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 org.springframework.data.gemfire.wan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.notNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Test;
import org.springframework.data.gemfire.TestUtils;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;
import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueue;
import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueueFactory;
import com.gemstone.gemfire.cache.util.Gateway;
/**
* The AsyncEventQueueFactoryBeanTest class is a test suite of test cases testing the contract and functionality
* of the AsyncEventQueueFactoryBean class.
*
* @author John Blum
* @see org.junit.Test
* @see org.mockito.Mockito
* @see org.springframework.data.gemfire.TestUtils
* @see org.springframework.data.gemfire.wan.AsyncEventQueueFactoryBean
* @see com.gemstone.gemfire.cache.Cache
* @see com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener
* @see com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueue
* @see com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueueFactory
* @since 1.3.3
*/
public class AsyncEventQueueFactoryBeanTest {
protected Cache createMockCacheWithAsyncEventQueueInfrastructure(
final AsyncEventQueueFactory mockAsynEventQueueFactory) {
Cache mockCache = mock(Cache.class);
when((mockCache.createAsyncEventQueueFactory())).thenReturn(mockAsynEventQueueFactory);
return mockCache;
}
protected AsyncEventQueueFactory createMockAsyncEventQueueFactory(final String asyncEventQueueId) {
AsyncEventQueueFactory mockAsyncEventQueueFactory = mock(AsyncEventQueueFactory.class);
AsyncEventQueue mockAsyncEventQueue = mock(AsyncEventQueue.class);
when(mockAsyncEventQueue.getId()).thenReturn(asyncEventQueueId);
when(mockAsyncEventQueueFactory.create(eq(asyncEventQueueId), notNull(AsyncEventListener.class)))
.thenReturn(mockAsyncEventQueue);
return mockAsyncEventQueueFactory;
}
protected AsyncEventListener createMockAsyncEventListener() {
return mock(AsyncEventListener.class);
}
protected void verifyExpectations(final AsyncEventQueueFactory mockAsyncEventQueueFactory,
final AsyncEventQueueFactoryBean factoryBean) throws Exception {
Boolean parallel = TestUtils.readField("parallel", factoryBean);
verify(mockAsyncEventQueueFactory).setParallel(eq(Boolean.TRUE.equals(parallel)));
String orderPolicy = TestUtils.readField("orderPolicy", factoryBean);
if (orderPolicy != null) {
verify(mockAsyncEventQueueFactory).setOrderPolicy(eq(Gateway.OrderPolicy.valueOf(orderPolicy.toUpperCase())));
}
Integer dispatcherThreads = TestUtils.readField("dispatcherThreads", factoryBean);
if (dispatcherThreads != null) {
verify(mockAsyncEventQueueFactory).setDispatcherThreads(eq(dispatcherThreads));
}
String diskStoreReference = TestUtils.readField("diskStoreReference", factoryBean);
if (diskStoreReference != null) {
verify(mockAsyncEventQueueFactory).setDiskStoreName(eq(diskStoreReference));
}
Boolean diskSynchronous = TestUtils.readField("diskSynchronous", factoryBean);
if (diskSynchronous != null) {
verify(mockAsyncEventQueueFactory).setDiskSynchronous(eq(diskSynchronous));
}
Boolean persistent = TestUtils.readField("persistent", factoryBean);
if (persistent != null) {
verify(mockAsyncEventQueueFactory).setPersistent(eq(persistent));
}
else {
verify(mockAsyncEventQueueFactory, never()).setPersistent(true);
}
}
@Test
public void testSetAsyncEventListener() throws Exception {
AsyncEventQueueFactoryBean factoryBean = new AsyncEventQueueFactoryBean(
createMockCacheWithAsyncEventQueueInfrastructure(createMockAsyncEventQueueFactory("testEventQueue")));
AsyncEventListener listenerOne = createMockAsyncEventListener();
factoryBean.setAsyncEventListener(listenerOne);
assertSame(listenerOne, TestUtils.readField("asyncEventListener", factoryBean));
AsyncEventListener listenerTwo = createMockAsyncEventListener();
factoryBean.setAsyncEventListener(listenerTwo);
assertSame(listenerTwo, TestUtils.readField("asyncEventListener", factoryBean));
}
@Test(expected = IllegalStateException.class)
public void testSetAsyncEventListenerAfterAsyncEventQueueCreation() throws Exception {
String asyncEventQueueId = "testEventQueue";
AsyncEventQueueFactoryBean factoryBean = new AsyncEventQueueFactoryBean(
createMockCacheWithAsyncEventQueueInfrastructure(createMockAsyncEventQueueFactory(asyncEventQueueId)));
factoryBean.setName(asyncEventQueueId);
AsyncEventListener listenerOne = createMockAsyncEventListener();
factoryBean.setAsyncEventListener(listenerOne);
assertSame(listenerOne, TestUtils.readField("asyncEventListener", factoryBean));
factoryBean.doInit();
assertNotNull(TestUtils.readField("asyncEventQueue", factoryBean));
try {
factoryBean.setAsyncEventListener(createMockAsyncEventListener());
}
catch (IllegalStateException expected) {
assertEquals("Setting an AsyncEventListener is not allowed once the AsyncEventQueue has been created.",
expected.getMessage());
assertSame(listenerOne, TestUtils.readField("asyncEventListener", factoryBean));
throw expected;
}
}
@Test(expected = IllegalArgumentException.class)
public void testDoInitWhenAsyncEventListenerIsNull() throws Exception {
try {
AsyncEventQueueFactoryBean factoryBean = new AsyncEventQueueFactoryBean(
createMockCacheWithAsyncEventQueueInfrastructure(createMockAsyncEventQueueFactory("testEventQueue")));
assertNull(TestUtils.readField("asyncEventListener", factoryBean));
factoryBean.doInit();
}
catch (Exception e) {
assertEquals("The AsyncEventListener cannot be null.", e.getMessage());
throw e;
}
}
@Test
public void testConcurrentParallelAsyncEventQueue() throws Exception {
AsyncEventQueueFactory mockAsyncEventQueueFactory = createMockAsyncEventQueueFactory("000");
AsyncEventQueueFactoryBean factoryBean = new AsyncEventQueueFactoryBean(
createMockCacheWithAsyncEventQueueInfrastructure(mockAsyncEventQueueFactory));
factoryBean.setName("000");
factoryBean.setAsyncEventListener(createMockAsyncEventListener());
factoryBean.setDispatcherThreads(8);
factoryBean.setParallel(true);
factoryBean.doInit();
verifyExpectations(mockAsyncEventQueueFactory, factoryBean);
AsyncEventQueue eventQueue = factoryBean.getObject();
assertNotNull(eventQueue);
assertEquals("000", eventQueue.getId());
}
@Test
public void testParallelAsyncEventQueue() throws Exception {
AsyncEventQueueFactory mockAsyncEventQueueFactory = createMockAsyncEventQueueFactory("123");
AsyncEventQueueFactoryBean factoryBean = new AsyncEventQueueFactoryBean(
createMockCacheWithAsyncEventQueueInfrastructure(mockAsyncEventQueueFactory));
factoryBean.setName("123");
factoryBean.setAsyncEventListener(createMockAsyncEventListener());
factoryBean.setParallel(true);
factoryBean.doInit();
verifyExpectations(mockAsyncEventQueueFactory, factoryBean);
AsyncEventQueue eventQueue = factoryBean.getObject();
assertNotNull(eventQueue);
assertEquals("123", eventQueue.getId());
}
@Test(expected = IllegalArgumentException.class)
public void testParallelAsyncEventQueueWithOrderPolicy() {
AsyncEventQueueFactory mockAsyncEventQueueFactory = createMockAsyncEventQueueFactory("456");
AsyncEventQueueFactoryBean factoryBean = new AsyncEventQueueFactoryBean(
createMockCacheWithAsyncEventQueueInfrastructure(mockAsyncEventQueueFactory));
factoryBean.setName("456");
factoryBean.setAsyncEventListener(createMockAsyncEventListener());
factoryBean.setOrderPolicy("Key");
factoryBean.setParallel(true);
try {
factoryBean.doInit();
}
catch (IllegalArgumentException expected) {
assertEquals("Order Policy cannot be used with a Parallel Event Queue.",
expected.getMessage());
throw expected;
}
}
@Test
public void testSerialAsyncEventQueueWithOrderPolicy() throws Exception {
AsyncEventQueueFactory mockAsyncEventQueueFatory = createMockAsyncEventQueueFactory("789");
AsyncEventQueueFactoryBean factoryBean = new AsyncEventQueueFactoryBean(
createMockCacheWithAsyncEventQueueInfrastructure(mockAsyncEventQueueFatory));
factoryBean.setName("789");
factoryBean.setAsyncEventListener(createMockAsyncEventListener());
factoryBean.setOrderPolicy("THREAD");
factoryBean.setParallel(false);
factoryBean.doInit();
verifyExpectations(mockAsyncEventQueueFatory, factoryBean);
AsyncEventQueue eventQueue = factoryBean.getObject();
assertNotNull(eventQueue);
assertEquals("789", eventQueue.getId());
}
@Test
public void testAsyncEventQueueWithOrderPolicyAndDispatcherThreads() throws Exception {
AsyncEventQueueFactory mockAsyncEventQueueFatory = createMockAsyncEventQueueFactory("abc");
AsyncEventQueueFactoryBean factoryBean = new AsyncEventQueueFactoryBean(
createMockCacheWithAsyncEventQueueInfrastructure(mockAsyncEventQueueFatory));
factoryBean.setName("abc");
factoryBean.setAsyncEventListener(createMockAsyncEventListener());
factoryBean.setDispatcherThreads(2);
factoryBean.setOrderPolicy("THREAD");
factoryBean.doInit();
verifyExpectations(mockAsyncEventQueueFatory, factoryBean);
AsyncEventQueue eventQueue = factoryBean.getObject();
assertNotNull(eventQueue);
assertEquals("abc", eventQueue.getId());
}
@Test
public void testAsyncEventQueueWithOverflowDiskStoreNoPersistence() throws Exception {
AsyncEventQueueFactory mockAsyncEventQueueFactory = createMockAsyncEventQueueFactory("123abc");
AsyncEventQueueFactoryBean factoryBean = new AsyncEventQueueFactoryBean(
createMockCacheWithAsyncEventQueueInfrastructure(mockAsyncEventQueueFactory));
factoryBean.setName("123abc");
factoryBean.setAsyncEventListener(createMockAsyncEventListener());
factoryBean.setDiskStoreRef("queueOverflowDiskStore");
factoryBean.setPersistent(false);
factoryBean.doInit();
verifyExpectations(mockAsyncEventQueueFactory, factoryBean);
AsyncEventQueue evenQueue = factoryBean.getObject();
assertNotNull(evenQueue);
assertEquals("123abc", evenQueue.getId());
}
@Test
public void testAsyncEventQueueWithDiskSynchronousSetPersistenceUnset() throws Exception {
AsyncEventQueueFactory mockAsyncEventQueueFactory = createMockAsyncEventQueueFactory("12345");
AsyncEventQueueFactoryBean factoryBean = new AsyncEventQueueFactoryBean(
createMockCacheWithAsyncEventQueueInfrastructure(mockAsyncEventQueueFactory));
factoryBean.setName("12345");
factoryBean.setAsyncEventListener(createMockAsyncEventListener());
factoryBean.setDiskSynchronous(true);
factoryBean.doInit();
verifyExpectations(mockAsyncEventQueueFactory, factoryBean);
AsyncEventQueue evenQueue = factoryBean.getObject();
assertNotNull(evenQueue);
assertEquals("12345", evenQueue.getId());
}
}