/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.regression.nwtable;
import com.espertech.esper.client.*;
import com.espertech.esper.client.scopetest.EPAssertionUtil;
import com.espertech.esper.client.scopetest.SupportUpdateListener;
import com.espertech.esper.supportregression.bean.SupportBean;
import com.espertech.esper.supportregression.bean.SupportBean_S0;
import com.espertech.esper.supportregression.client.SupportConfigFactory;
import junit.framework.TestCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestTableMTAccessReadMergeWriteInsertDeleteRowVisible extends TestCase
{
private static final Logger log = LoggerFactory.getLogger(TestTableMTAccessReadMergeWriteInsertDeleteRowVisible.class);
private EPServiceProvider epService;
public void setUp()
{
Configuration config = SupportConfigFactory.getConfiguration();
config.addEventType(SupportBean.class);
config.addEventType(SupportBean_S0.class);
epService = EPServiceProviderManager.getDefaultProvider(config);
epService.initialize();
}
/**
* Table:
* create table MyTable(key string primary key, p0 int, p1 int, p2, int, p3 int, p4 int)
*
* For a given number of seconds:
* - Single writer uses merge in a loop:
* - inserts MyTable={key='K1', p0=1, p1=1, p2=1, p3=1, p4=1}
* - deletes the row
* - Single reader outputs p0 to p4 using "MyTable['K1'].px"
* Row should either exist with all values found or not exist.
*/
public void testMTGrouped() throws Exception {
tryMT(1, true);
}
public void testMTUngrouped() throws Exception {
tryMT(1, false);
}
private void tryMT(int numSeconds, boolean grouped) throws Exception {
String eplCreateTable = "create table MyTable (key string " + (grouped ? "primary key" : "") +
", p0 int, p1 int, p2 int, p3 int, p4 int, p5 int)";
epService.getEPAdministrator().createEPL(eplCreateTable);
String eplSelect = grouped ?
"select MyTable['K1'].p0 as c0, MyTable['K1'].p1 as c1, MyTable['K1'].p2 as c2, " +
"MyTable['K1'].p3 as c3, MyTable['K1'].p4 as c4, MyTable['K1'].p5 as c5 from SupportBean_S0"
:
"select MyTable.p0 as c0, MyTable.p1 as c1, MyTable.p2 as c2, " +
"MyTable.p3 as c3, MyTable.p4 as c4, MyTable.p5 as c5 from SupportBean_S0";
EPStatement stmt = epService.getEPAdministrator().createEPL(eplSelect);
SupportUpdateListener listener = new SupportUpdateListener();
stmt.addListener(listener);
String eplMerge = "on SupportBean merge MyTable " +
"when not matched then insert select 'K1' as key, 1 as p0, 1 as p1, 1 as p2, 1 as p3, 1 as p4, 1 as p5 " +
"when matched then delete";
epService.getEPAdministrator().createEPL(eplMerge);
WriteRunnable writeRunnable = new WriteRunnable(epService);
ReadRunnable readRunnable = new ReadRunnable(epService, listener);
// start
Thread t1 = new Thread(writeRunnable);
Thread t2 = new Thread(readRunnable);
t1.start();
t2.start();
// wait
Thread.sleep(numSeconds * 1000);
// shutdown
writeRunnable.setShutdown(true);
readRunnable.setShutdown(true);
// join
log.info("Waiting for completion");
t1.join();
t2.join();
assertNull(writeRunnable.getException());
assertTrue(writeRunnable.numEvents > 100);
assertNull(readRunnable.getException());
assertTrue(readRunnable.numQueries > 100);
assertTrue(readRunnable.getNotFoundCount() > 2);
assertTrue(readRunnable.getFoundCount() > 2);
System.out.println("Send " + writeRunnable.numEvents + " and performed " + readRunnable.numQueries +
" reads (found " + readRunnable.getFoundCount() + ") (not found " + readRunnable.getNotFoundCount() + ")");
}
public static class WriteRunnable implements Runnable {
private final EPServiceProvider epService;
private RuntimeException exception;
private boolean shutdown;
private int numEvents;
public WriteRunnable(EPServiceProvider epService) {
this.epService = epService;
}
public void setShutdown(boolean shutdown) {
this.shutdown = shutdown;
}
public void run() {
log.info("Started event send for write");
try {
while(!shutdown) {
epService.getEPRuntime().sendEvent(new SupportBean(null, 0));
numEvents++;
}
}
catch (RuntimeException ex) {
log.error("Exception encountered: " + ex.getMessage(), ex);
exception = ex;
}
log.info("Completed event send for write");
}
public RuntimeException getException() {
return exception;
}
}
public static class ReadRunnable implements Runnable {
private final EPServiceProvider epService;
private final SupportUpdateListener listener;
private RuntimeException exception;
private boolean shutdown;
private int numQueries;
private int foundCount;
private int notFoundCount;
public ReadRunnable(EPServiceProvider epService, SupportUpdateListener listener) {
this.epService = epService;
this.listener = listener;
}
public void setShutdown(boolean shutdown) {
this.shutdown = shutdown;
}
public void run() {
log.info("Started event send for read");
try {
String[] fields = "c0,c1,c2,c3,c4,c5".split(",");
Object[] expected = new Object[] {1, 1, 1, 1, 1, 1};
while(!shutdown) {
epService.getEPRuntime().sendEvent(new SupportBean_S0(0));
EventBean event = listener.assertOneGetNewAndReset();
if (event.get("c0") == null) {
notFoundCount++;
}
else {
foundCount++;
EPAssertionUtil.assertProps(event, fields, expected);
}
numQueries++;
}
}
catch (RuntimeException ex) {
log.error("Exception encountered: " + ex.getMessage(), ex);
exception = ex;
}
log.info("Completed event send for read");
}
public RuntimeException getException() {
return exception;
}
public int getFoundCount() {
return foundCount;
}
public int getNotFoundCount() {
return notFoundCount;
}
}
}