package com.alibaba.cobar.client;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertNull;
import static org.testng.AssertJUnit.assertTrue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.ArrayUtils;
import org.testng.annotations.Test;
import com.alibaba.cobar.client.entities.Offer;
import com.alibaba.cobar.client.support.utils.CollectionUtils;
import com.alibaba.cobar.client.support.vo.BatchInsertTask;
@Test(sequential=true)
public class CobarSqlMapClientTemplateWithComposedRuleRouterTest extends
AbstractTestNGCobarClientTest {
private static final String OFFER_CREATION_SQL = "com.alibaba.cobar.client.entities.Offer.create";
public CobarSqlMapClientTemplateWithComposedRuleRouterTest() {
super(new String[] { "META-INF/spring/cobar-client-appctx.xml",
"META-INF/spring/datasources-appctx.xml",
"META-INF/spring/namespace-sqlaction-composed-router-appctx.xml" });
}
public void testInsertOnCobarSqlMapClientTemplate() {
Offer offer = new Offer();
offer.setGmtUpdated(new Date());
offer.setMemberId(129L);
offer.setSubject("some offer");
Object pk = getSqlMapClientTemplate().insert(OFFER_CREATION_SQL, offer);
assertNotNull(pk);
String confirmSQL = "SELECT memberId FROM offers where id=" + pk;
verifyEntityExistenceOnSpecificDataSource(confirmSQL, jt1m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt1s);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt2m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt2s);
offer = new Offer();
offer.setGmtUpdated(new Date());
offer.setMemberId(130L);
offer.setSubject("some offer");
pk = null;
pk = getSqlMapClientTemplate().insert(OFFER_CREATION_SQL, offer);
assertNotNull(pk);
confirmSQL = "SELECT memberId FROM offers where id=" + pk;
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt1s);
verifyEntityExistenceOnSpecificDataSource(confirmSQL, jt2m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt2s);
}
public void testInsertOnCobarSqlMapClientTemplateWithoutFoundRule() {
Offer offer = new Offer();
offer.setGmtUpdated(new Date());
offer.setMemberId(128L);
offer.setSubject("some offer");
Object pk = getSqlMapClientTemplate().insert(OFFER_CREATION_SQL, offer);
assertNotNull(pk);
String confirmSQL = "SELECT memberId FROM offers where id=" + pk;
verifyEntityExistenceOnSpecificDataSource(confirmSQL, jt1m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt1s);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt2m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt2s);
}
public void testBatchInsertOnCobarClientTemplateNormally() {
Long[] memberIds = new Long[] { 1L, 129L, 257L, 2L, 130L, 258L, 386L };
Object pk = batchInsertOffersAsFixtureForLaterUse(memberIds);
assertNotNull(pk);
assertTrue(pk instanceof Collection<?>);
for (int i = 0; i < memberIds.length; i++) {
String confirmSQL = "select subject from offers where memberId=" + memberIds[i];
if (i < 3) {
verifyEntityExistenceOnSpecificDataSource(confirmSQL, jt1m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt1s);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt2m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt2s);
} else {
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt1m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt1s);
verifyEntityExistenceOnSpecificDataSource(confirmSQL, jt2m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt2s);
}
}
}
public void testDeleteOnCobarSqlMapClientTemplateNormally() {
Long[] memberIds = new Long[] { 1L, 129L, 257L, 2L, 130L, 258L, 386L };
// 1. empty data bases
String sqlAction = "com.alibaba.cobar.client.entities.Offer.deleteByMemberId";
for (Long mid : memberIds) {
Offer offer = new Offer();
offer.setMemberId(mid);
int affectedRows = getSqlMapClientTemplate().delete(sqlAction, offer);
assertEquals(0, affectedRows);
}
// 2. insert data fixtures
batchInsertOffersAsFixtureForLaterUse(memberIds);
for (int i = 0; i < memberIds.length; i++) {
String confirmSQL = "select subject from offers where memberId=" + memberIds[i];
if (i < 3) {
verifyEntityExistenceOnSpecificDataSource(confirmSQL, jt1m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt1s);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt2m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt2s);
} else {
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt1m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt1s);
verifyEntityExistenceOnSpecificDataSource(confirmSQL, jt2m);
verifyEntityNonExistenceOnSpecificDataSource(confirmSQL, jt2s);
}
}
// 3. perform deletion and assertion
for (Long mid : memberIds) {
Offer offer = new Offer();
offer.setMemberId(mid);
int affectedRows = getSqlMapClientTemplate().delete(sqlAction, offer);
assertEquals(1, affectedRows);
}
}
public void testDeleteOnCobarSqlMapClientTemplateAbnormally() {
Long[] memberIds = new Long[] { 1L, 129L, 257L, 2L, 130L, 258L, 386L };
batchInsertOffersAsFixtureForLaterUse(memberIds);
String deleteSqlAction = "com.alibaba.cobar.client.entities.Offer.delete";
// no rule can be found for this, so currently, it will be performed against default data source
for (int i = 0; i < memberIds.length; i++) {
String selectSQL = "select id from offers where memberId=" + memberIds[i];
if (i < 3) {
Long id = jt1m.queryForLong(selectSQL);
int affectedRows = getSqlMapClientTemplate().delete(deleteSqlAction, id);
assertEquals(1, affectedRows);
} else {
Long id = jt2m.queryForLong(selectSQL);
int affectedRows = getSqlMapClientTemplate().delete(deleteSqlAction, id);
assertEquals(0, affectedRows);
}
}
}
@SuppressWarnings("unchecked")
public void testQueryForListOnCobarSqlMapClientTemplateNormally() {
Long[] memberIds = new Long[] { 1L, 129L, 257L, 2L, 130L, 258L, 386L };
batchInsertOffersAsFixtureForLaterUse(memberIds);
List<Offer> offers = (List<Offer>) getSqlMapClientTemplate().queryForList(
"com.alibaba.cobar.client.entities.Offer.findAll");
assertTrue(CollectionUtils.isNotEmpty(offers));
assertEquals(7, offers.size());
for (Offer offer : offers) {
assertTrue(ArrayUtils.contains(memberIds, offer.getMemberId()));
}
offers = null;
offers = (List<Offer>) getSqlMapClientTemplate().queryForList(
"com.alibaba.cobar.client.entities.Offer.findByMemberIdRange", 300L);
assertTrue(CollectionUtils.isNotEmpty(offers));
assertEquals(3, offers.size());
Long[] partialMemberIds = new Long[] { 1L, 129L, 257L };
for (Offer offer : offers) {
assertTrue(ArrayUtils.contains(partialMemberIds, offer.getMemberId()));
}
}
public void testQueryForObjectOnCobarSqlMapClientTemplateNormally() {
Long[] memberIds = new Long[] { 1L, 129L, 257L, 2L, 130L, 258L, 386L };
batchInsertOffersAsFixtureForLaterUse(memberIds);
// scenario 1: no routing rules are found for current sql action, so only records residing on default data source can be returned.
String selectSqlActionOne = "com.alibaba.cobar.client.entities.Offer.load";
for (int i = 0; i < memberIds.length; i++) {
String confirmSQL = "select id from offers where memberId=" + memberIds[i];
if (i < 3) {
Long id = jt1m.queryForLong(confirmSQL);
Offer offer = (Offer) getSqlMapClientTemplate().queryForObject(selectSqlActionOne,
id);
assertNotNull(offer);
assertEquals(memberIds[i], offer.getMemberId());
} else {
Long id = jt2m.queryForLong(confirmSQL);
Offer offer = (Offer) getSqlMapClientTemplate().queryForObject(selectSqlActionOne,
id);
assertNull(offer);
}
}
// scenario 2: fallback sharding rules can be found for current sql action, so all requested records are returned normally.
String selectSqlActionTwo = "com.alibaba.cobar.client.entities.Offer.findByMemberId";
for (Long mid : memberIds) {
Offer parameter = new Offer();
parameter.setMemberId(mid);
Offer offer = (Offer) getSqlMapClientTemplate().queryForObject(selectSqlActionTwo,
parameter);
assertNotNull(offer);
assertEquals(mid, offer.getMemberId());
}
}
public void testUpdateOnCobarSqlMapClientTemplateNormally() {
Long[] memberIds = new Long[] { 1L, 129L, 257L, 2L, 130L, 258L, 386L };
batchInsertOffersAsFixtureForLaterUse(memberIds);
String selectSqlActionTwo = "com.alibaba.cobar.client.entities.Offer.findByMemberId";
String offerSubject = "_SUBEJCT_";
for (Long mid : memberIds) {
// 1. assertion before update
Offer parameter = new Offer();
parameter.setMemberId(mid);
Offer offer = (Offer) getSqlMapClientTemplate().queryForObject(selectSqlActionTwo,
parameter);
assertNotNull(offer);
assertEquals("fake offer", offer.getSubject());
// 2. assertion on update
offer.setSubject(offerSubject);
int affectedRows = getSqlMapClientTemplate().update(
"com.alibaba.cobar.client.entities.Offer.update", offer);
assertEquals(1, affectedRows);
// 3. assertion after update
offer = null;
offer = (Offer) getSqlMapClientTemplate().queryForObject(selectSqlActionTwo, parameter);
assertNotNull(offer);
assertEquals(offerSubject, offer.getSubject());
}
}
private Object batchInsertOffersAsFixtureForLaterUse(Long[] memberIds) {
List<Offer> offers = new ArrayList<Offer>();
for (Long mid : memberIds) {
Offer offer = new Offer();
offer.setGmtUpdated(new Date());
offer.setMemberId(mid);
offer.setSubject("fake offer");
offers.add(offer);
}
Object pk = getSqlMapClientTemplate().insert(
"com.alibaba.cobar.client.entities.Offer.batchInsert", new BatchInsertTask(offers));
return pk;
}
}