/*
***************************************************************************************
* 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.rowrecog;
import com.espertech.esper.client.Configuration;
import com.espertech.esper.client.EPServiceProvider;
import com.espertech.esper.client.EPServiceProviderManager;
import com.espertech.esper.client.EPStatement;
import com.espertech.esper.client.hook.ConditionHandlerContext;
import com.espertech.esper.client.hook.ConditionHandlerFactoryContext;
import com.espertech.esper.client.hook.ConditionMatchRecognizeStatesMax;
import com.espertech.esper.client.scopetest.EPAssertionUtil;
import com.espertech.esper.client.scopetest.SupportUpdateListener;
import com.espertech.esper.metrics.instrumentation.InstrumentationHelper;
import com.espertech.esper.supportregression.bean.SupportBean;
import com.espertech.esper.supportregression.bean.SupportBeanConstants;
import com.espertech.esper.supportregression.bean.SupportBean_S0;
import com.espertech.esper.supportregression.bean.SupportBean_S1;
import com.espertech.esper.supportregression.client.SupportConditionHandlerFactory;
import com.espertech.esper.supportregression.client.SupportConfigFactory;
import junit.framework.TestCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TestRowPatternMaxStatesEngineWide extends TestCase implements SupportBeanConstants
{
private EPServiceProvider epService;
private SupportConditionHandlerFactory.SupportConditionHandler handler;
private SupportUpdateListener listenerOne;
private SupportUpdateListener listenerTwo;
public void setUp() throws Exception {
listenerOne = new SupportUpdateListener();
listenerTwo = new SupportUpdateListener();
}
protected void tearDown() throws Exception {
handler = null;
}
public void testReportDontPreventandRuntimeConfig() {
String[] fields = "c0".split(",");
initService(3L, false);
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());}
String epl = "@name('S1') select * from SupportBean " +
"match_recognize (" +
" partition by theString " +
" measures P1.theString as c0" +
" pattern (P1 P2) " +
" define " +
" P1 as P1.intPrimitive = 1," +
" P2 as P2.intPrimitive = 2" +
")";
SupportUpdateListener listener = new SupportUpdateListener();
EPStatement stmt = epService.getEPAdministrator().createEPL(epl);
stmt.addListener(listener);
epService.getEPRuntime().sendEvent(new SupportBean("A", 1));
epService.getEPRuntime().sendEvent(new SupportBean("B", 1));
epService.getEPRuntime().sendEvent(new SupportBean("C", 1));
assertTrue(handler.getContexts().isEmpty());
// overflow
epService.getEPRuntime().sendEvent(new SupportBean("D", 1));
assertContextEnginePool(epService, stmt, handler.getAndResetContexts(), 3, getExpectedCountMap("S1", 3));
epService.getEPRuntime().sendEvent(new SupportBean("E", 1));
assertContextEnginePool(epService, stmt, handler.getAndResetContexts(), 3, getExpectedCountMap("S1", 4));
epService.getEPRuntime().sendEvent(new SupportBean("D", 2)); // D gone
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"D"});
epService.getEPRuntime().sendEvent(new SupportBean("A", 2)); // A gone
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"A"});
epService.getEPRuntime().sendEvent(new SupportBean("C", 2)); // C gone
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"C"});
epService.getEPRuntime().sendEvent(new SupportBean("F", 1));
assertTrue(handler.getContexts().isEmpty());
epService.getEPRuntime().sendEvent(new SupportBean("G", 1));
assertContextEnginePool(epService, stmt, handler.getAndResetContexts(), 3, getExpectedCountMap("S1", 3));
epService.getEPAdministrator().getConfiguration().setMatchRecognizeMaxStates(4L);
epService.getEPRuntime().sendEvent(new SupportBean("G", 1));
assertTrue(handler.getContexts().isEmpty());
epService.getEPRuntime().sendEvent(new SupportBean("H", 1));
assertContextEnginePool(epService, stmt, handler.getAndResetContexts(), 4, getExpectedCountMap("S1", 4));
epService.getEPAdministrator().getConfiguration().setMatchRecognizeMaxStates(null);
epService.getEPRuntime().sendEvent(new SupportBean("I", 1));
assertTrue(handler.getContexts().isEmpty());
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();}
}
public void testTwoStatementNoDelete()
{
String[] fields = "c0".split(",");
initService(3L, true);
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());}
String eplOne = "@name('S1') select * from SupportBean(theString='A') " +
"match_recognize (" +
" measures P1.longPrimitive as c0" +
" pattern (P1 P2 P3) " +
" define " +
" P1 as P1.intPrimitive = 1," +
" P2 as P2.intPrimitive = 1," +
" P3 as P3.intPrimitive = 2 and P3.longPrimitive = P1.longPrimitive" +
")";
EPStatement stmtOne = epService.getEPAdministrator().createEPL(eplOne);
stmtOne.addListener(listenerOne);
String eplTwo = "@name('S2') select * from SupportBean(theString='B') " +
"match_recognize (" +
" measures P1.longPrimitive as c0" +
" pattern (P1 P2 P3) " +
" define " +
" P1 as P1.intPrimitive = 1," +
" P2 as P2.intPrimitive = 1," +
" P3 as P3.intPrimitive = 2 and P3.longPrimitive = P1.longPrimitive" +
")";
EPStatement stmtTwo = epService.getEPAdministrator().createEPL(eplTwo);
stmtTwo.addListener(listenerTwo);
epService.getEPRuntime().sendEvent(makeBean("A", 1, 10)); // A(10):P1->P2
epService.getEPRuntime().sendEvent(makeBean("B", 1, 11)); // A(10):P1->P2, B(11):P1->P2
epService.getEPRuntime().sendEvent(makeBean("A", 1, 12)); // A(10):P2->P3, A(12):P1->P2, B(11):P1->P2
assertTrue(handler.getContexts().isEmpty());
// overflow
epService.getEPRuntime().sendEvent(makeBean("B", 1, 13)); // would be: A(10):P2->P3, A(12):P1->P2, B(11):P2->P3, B(13):P1->P2
assertContextEnginePool(epService, stmtTwo, handler.getAndResetContexts(), 3, getExpectedCountMap("S1", 2, "S2", 1));
// terminate B
epService.getEPRuntime().sendEvent(makeBean("B", 2, 11)); // we have no more B-state
EPAssertionUtil.assertProps(listenerTwo.assertOneGetNewAndReset(), fields, new Object[] {11L});
// should not overflow
epService.getEPRuntime().sendEvent(makeBean("B", 1, 15));
assertTrue(handler.getContexts().isEmpty());
// overflow
epService.getEPRuntime().sendEvent(makeBean("B", 1, 16));
assertContextEnginePool(epService, stmtTwo, handler.getAndResetContexts(), 3, getExpectedCountMap("S1", 2, "S2", 1));
// terminate A
epService.getEPRuntime().sendEvent(makeBean("A", 2, 10)); // we have no more A-state
EPAssertionUtil.assertProps(listenerOne.assertOneGetNewAndReset(), fields, new Object[] {10L});
// should not overflow
epService.getEPRuntime().sendEvent(makeBean("B", 1, 17));
epService.getEPRuntime().sendEvent(makeBean("B", 1, 18));
epService.getEPRuntime().sendEvent(makeBean("A", 1, 19));
assertTrue(handler.getContexts().isEmpty());
// overflow
epService.getEPRuntime().sendEvent(makeBean("A", 1, 20));
assertContextEnginePool(epService, stmtOne, handler.getAndResetContexts(), 3, getExpectedCountMap("S1", 1, "S2", 2));
// terminate B
epService.getEPRuntime().sendEvent(makeBean("B", 2, 17));
EPAssertionUtil.assertProps(listenerTwo.assertOneGetNewAndReset(), fields, new Object[] {17L});
// terminate A
epService.getEPRuntime().sendEvent(makeBean("A", 2, 19));
EPAssertionUtil.assertProps(listenerOne.assertOneGetNewAndReset(), fields, new Object[] {19L});
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();}
}
public void testDataWindowAndStmtStop()
{
String[] fields = "c0".split(",");
initService(4L, true);
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());}
String eplOne = "@name('S1') select * from SupportBean(theString = 'A') " +
"match_recognize (" +
" partition by intPrimitive " +
" measures P2.intPrimitive as c0" +
" pattern (P1 P2) " +
" define " +
" P1 as P1.longPrimitive = 1," +
" P2 as P2.longPrimitive = 2" +
")";
EPStatement stmtOne = epService.getEPAdministrator().createEPL(eplOne);
stmtOne.addListener(listenerOne);
String eplTwo = "@name('S2') select * from SupportBean(theString = 'B')#length(2) " +
"match_recognize (" +
" partition by intPrimitive " +
" measures P2.intPrimitive as c0" +
" pattern (P1 P2) " +
" define " +
" P1 as P1.longPrimitive = 1," +
" P2 as P2.longPrimitive = 2" +
")";
EPStatement stmtTwo = epService.getEPAdministrator().createEPL(eplTwo);
stmtTwo.addListener(listenerTwo);
epService.getEPRuntime().sendEvent(makeBean("A", 100, 1));
epService.getEPRuntime().sendEvent(makeBean("A", 200, 1));
epService.getEPRuntime().sendEvent(makeBean("B", 100, 1));
epService.getEPRuntime().sendEvent(makeBean("B", 200, 1));
epService.getEPRuntime().sendEvent(makeBean("B", 300, 1));
epService.getEPRuntime().sendEvent(makeBean("B", 400, 1));
EPAssertionUtil.iteratorToArray(stmtTwo.iterator());
assertTrue(handler.getContexts().isEmpty());
// overflow
epService.getEPRuntime().sendEvent(makeBean("A", 300, 1));
assertContextEnginePool(epService, stmtOne, handler.getAndResetContexts(), 4, getExpectedCountMap("S1", 2, "S2", 2));
// terminate B
epService.getEPRuntime().sendEvent(makeBean("B", 400, 2));
EPAssertionUtil.assertProps(listenerTwo.assertOneGetNewAndReset(), fields, new Object[] {400});
// terminate one of A
epService.getEPRuntime().sendEvent(makeBean("A", 100, 2));
EPAssertionUtil.assertProps(listenerOne.assertOneGetNewAndReset(), fields, new Object[] {100});
// fill up A
epService.getEPRuntime().sendEvent(makeBean("A", 300, 1));
epService.getEPRuntime().sendEvent(makeBean("A", 400, 1));
epService.getEPRuntime().sendEvent(makeBean("A", 500, 1));
assertTrue(handler.getContexts().isEmpty());
// overflow
epService.getEPRuntime().sendEvent(makeBean("B", 500, 1));
assertContextEnginePool(epService, stmtTwo, handler.getAndResetContexts(), 4, getExpectedCountMap("S1", 4, "S2", 0));
// destroy statement-1 freeing up all "A"
stmtOne.destroy();
// any number of B doesn't trigger overflow because of data window
epService.getEPRuntime().sendEvent(makeBean("B", 600, 1));
epService.getEPRuntime().sendEvent(makeBean("B", 700, 1));
epService.getEPRuntime().sendEvent(makeBean("B", 800, 1));
epService.getEPRuntime().sendEvent(makeBean("B", 900, 1));
assertTrue(handler.getContexts().isEmpty());
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();}
}
public void testContextPartitionAndOverflow()
{
String[] fields = "c0".split(",");
initService(3L, true);
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());}
String eplCtx = "create context MyCtx initiated by SupportBean_S0 as s0 terminated by SupportBean_S1(p10 = s0.p00)";
epService.getEPAdministrator().createEPL(eplCtx);
String epl = "@name('S1') context MyCtx select * from SupportBean(theString = context.s0.p00) " +
"match_recognize (" +
" measures P2.theString as c0" +
" pattern (P1 P2) " +
" define " +
" P1 as P1.intPrimitive = 1," +
" P2 as P2.intPrimitive = 2" +
")";
SupportUpdateListener listener = new SupportUpdateListener();
EPStatement stmt = epService.getEPAdministrator().createEPL(epl);
stmt.addListener(listener);
epService.getEPRuntime().sendEvent(new SupportBean_S0(0, "A"));
epService.getEPRuntime().sendEvent(new SupportBean("A", 1));
epService.getEPRuntime().sendEvent(new SupportBean_S0(0, "B"));
epService.getEPRuntime().sendEvent(new SupportBean("B", 1));
epService.getEPRuntime().sendEvent(new SupportBean_S0(0, "C"));
epService.getEPRuntime().sendEvent(new SupportBean("C", 1));
epService.getEPRuntime().sendEvent(new SupportBean_S0(0, "D"));
assertTrue(handler.getContexts().isEmpty());
epService.getEPRuntime().sendEvent(new SupportBean("D", 1));
assertContextEnginePool(epService, stmt, handler.getAndResetContexts(), 3, getExpectedCountMap("S1", 3));
// terminate a context partition
epService.getEPRuntime().sendEvent(new SupportBean_S1(0, "D"));
epService.getEPRuntime().sendEvent(new SupportBean("D", 1));
epService.getEPRuntime().sendEvent(new SupportBean_S0(0, "E"));
assertTrue(handler.getContexts().isEmpty());
epService.getEPRuntime().sendEvent(new SupportBean("E", 1));
assertContextEnginePool(epService, stmt, handler.getAndResetContexts(), 3, getExpectedCountMap("S1", 3));
epService.getEPRuntime().sendEvent(new SupportBean("A", 2));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"A"});
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();}
}
public void testNamedWindowInSequenceRemoveEvent()
{
String[] fields = "c0,c1".split(",");
initService(3L, true);
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());}
String namedWindow = "create window MyWindow#keepall as SupportBean";
epService.getEPAdministrator().createEPL(namedWindow);
String insert = "insert into MyWindow select * from SupportBean";
epService.getEPAdministrator().createEPL(insert);
String delete = "on SupportBean_S0 delete from MyWindow where theString = p00";
epService.getEPAdministrator().createEPL(delete);
String epl = "@name('S1') select * from MyWindow " +
"match_recognize (" +
" partition by theString " +
" measures P1.longPrimitive as c0, P2.longPrimitive as c1" +
" pattern (P1 P2) " +
" define " +
" P1 as P1.intPrimitive = 0," +
" P2 as P2.intPrimitive = 1" +
")";
SupportUpdateListener listener = new SupportUpdateListener();
EPStatement stmt = epService.getEPAdministrator().createEPL(epl);
stmt.addListener(listener);
epService.getEPRuntime().sendEvent(makeBean("A", 0, 1));
epService.getEPRuntime().sendEvent(makeBean("B", 0, 2));
epService.getEPRuntime().sendEvent(makeBean("C", 0, 3));
assertTrue(handler.getContexts().isEmpty());
// overflow
epService.getEPRuntime().sendEvent(makeBean("D", 0, 4));
assertContextEnginePool(epService, stmt, handler.getAndResetContexts(), 3, getExpectedCountMap("S1", 3));
// delete A (in-sequence remove)
epService.getEPRuntime().sendEvent(new SupportBean_S0(1, "A"));
epService.getEPRuntime().sendEvent(makeBean("D", 0, 5)); // now 3 states: B, C, D
assertTrue(handler.getContexts().isEmpty());
// test matching
epService.getEPRuntime().sendEvent(makeBean("B", 1, 6)); // now 2 states: C, D
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {2L, 6L});
// no overflows
epService.getEPRuntime().sendEvent(makeBean("E", 0, 7));
assertTrue(handler.getContexts().isEmpty());
// overflow
epService.getEPRuntime().sendEvent(makeBean("F", 0, 9));
assertContextEnginePool(epService, stmt, handler.getAndResetContexts(), 3, getExpectedCountMap("S1", 3));
// no match expected
epService.getEPRuntime().sendEvent(makeBean("F", 1, 10));
assertFalse(listener.isInvoked());
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();}
}
public void testNamedWindowOutOfSequenceRemoveEvent()
{
String[] fields = "c0,c1,c2".split(",");
initService(3L, true);
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());}
String namedWindow = "create window MyWindow#keepall as SupportBean";
epService.getEPAdministrator().createEPL(namedWindow);
String insert = "insert into MyWindow select * from SupportBean";
epService.getEPAdministrator().createEPL(insert);
String delete = "on SupportBean_S0 delete from MyWindow where theString = p00 and intPrimitive = id";
epService.getEPAdministrator().createEPL(delete);
String epl = "@name('S1') select * from MyWindow " +
"match_recognize (" +
" partition by theString " +
" measures P1.longPrimitive as c0, P2.longPrimitive as c1, P3.longPrimitive as c2" +
" pattern (P1 P2 P3) " +
" define " +
" P1 as P1.intPrimitive = 0," +
" P2 as P2.intPrimitive = 1," +
" P3 as P3.intPrimitive = 2" +
")";
SupportUpdateListener listener = new SupportUpdateListener();
EPStatement stmt = epService.getEPAdministrator().createEPL(epl);
stmt.addListener(listener);
epService.getEPRuntime().sendEvent(makeBean("A", 0, 1));
epService.getEPRuntime().sendEvent(makeBean("A", 1, 2));
epService.getEPRuntime().sendEvent(makeBean("B", 0, 3));
assertTrue(handler.getContexts().isEmpty());
// delete A-1 (out-of-sequence remove)
epService.getEPRuntime().sendEvent(new SupportBean_S0(1, "A"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(0, "A"));
epService.getEPRuntime().sendEvent(makeBean("A", 2, 4));
assertFalse(listener.isInvoked());
assertTrue(handler.getContexts().isEmpty()); // states: B
// test overflow
epService.getEPRuntime().sendEvent(makeBean("C", 0, 5));
epService.getEPRuntime().sendEvent(makeBean("D", 0, 6));
assertTrue(handler.getContexts().isEmpty());
// overflow
epService.getEPRuntime().sendEvent(makeBean("E", 0, 7));
assertContextEnginePool(epService, stmt, handler.getAndResetContexts(), 3, getExpectedCountMap("S1", 3));
// assert nothing matches for overflowed and deleted
epService.getEPRuntime().sendEvent(makeBean("E", 1, 8));
epService.getEPRuntime().sendEvent(makeBean("E", 2, 9));
epService.getEPRuntime().sendEvent(new SupportBean_S0(0, "C")); // delete c
epService.getEPRuntime().sendEvent(makeBean("C", 1, 10));
epService.getEPRuntime().sendEvent(makeBean("C", 2, 11));
assertFalse(listener.isInvoked());
// assert match found for B
epService.getEPRuntime().sendEvent(makeBean("B", 1, 12));
epService.getEPRuntime().sendEvent(makeBean("B", 2, 13));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {3L, 12L, 13L});
// no overflow
epService.getEPRuntime().sendEvent(makeBean("F", 0, 14));
epService.getEPRuntime().sendEvent(makeBean("G", 0, 15));
assertTrue(handler.getContexts().isEmpty());
// overflow
epService.getEPRuntime().sendEvent(makeBean("H", 0, 16));
assertContextEnginePool(epService, stmt, handler.getAndResetContexts(), 3, getExpectedCountMap("S1", 3));
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();}
}
private void initService(long max, boolean preventStart) {
Configuration config = SupportConfigFactory.getConfiguration();
config.addEventType(SupportBean.class);
config.addEventType(SupportBean_S0.class);
config.addEventType(SupportBean_S1.class);
config.getEngineDefaults().getConditionHandling().addClass(SupportConditionHandlerFactory.class);
config.getEngineDefaults().getMatchRecognize().setMaxStates(max);
config.getEngineDefaults().getMatchRecognize().setMaxStatesPreventStart(preventStart);
config.getEngineDefaults().getLogging().setEnableExecutionDebug(true);
epService = EPServiceProviderManager.getDefaultProvider(config);
epService.initialize();
ConditionHandlerFactoryContext context = SupportConditionHandlerFactory.getFactoryContexts().get(0);
assertEquals(epService.getURI(), context.getEngineURI());
handler = SupportConditionHandlerFactory.getLastHandler();
}
private static void assertContextEnginePool(EPServiceProvider epService, EPStatement stmt, List<ConditionHandlerContext> contexts, int max, Map<String, Long> counts) {
assertEquals(1, contexts.size());
ConditionHandlerContext context = contexts.get(0);
assertEquals(epService.getURI(), context.getEngineURI());
assertEquals(stmt.getText(), context.getEpl());
assertEquals(stmt.getName(), context.getStatementName());
ConditionMatchRecognizeStatesMax condition = (ConditionMatchRecognizeStatesMax) context.getEngineCondition();
assertEquals(max, condition.getMax());
assertEquals(counts.size(), condition.getCounts().size());
for (Map.Entry<String, Long> expected : counts.entrySet()) {
assertEquals("failed for key " + expected.getKey(), expected.getValue(), condition.getCounts().get(expected.getKey()));
}
contexts.clear();
}
private static Map<String, Long> getExpectedCountMap(String stmtOne, long countOne, String stmtTwo, long countTwo) {
Map<String, Long> result = new HashMap<String, Long>();
result.put(stmtOne, countOne);
result.put(stmtTwo, countTwo);
return result;
}
private static Map<String, Long> getExpectedCountMap(String stmtOne, long countOne) {
Map<String, Long> result = new HashMap<String, Long>();
result.put(stmtOne, countOne);
return result;
}
private static SupportBean makeBean(String theString, int intPrimitive, long longPrimitive) {
SupportBean supportBean = new SupportBean(theString, intPrimitive);
supportBean.setLongPrimitive(longPrimitive);
return supportBean;
}
private final static Logger log = LoggerFactory.getLogger(TestRowPatternMaxStatesEngineWide.class);
}