/*
***************************************************************************************
* 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.context;
import com.espertech.esper.client.*;
import com.espertech.esper.client.context.ContextPartitionSelectorAll;
import com.espertech.esper.client.scopetest.EPAssertionUtil;
import com.espertech.esper.client.scopetest.SupportUpdateListener;
import com.espertech.esper.client.soda.EPStatementObjectModel;
import com.espertech.esper.core.service.EPContextPartitionAdminSPI;
import com.espertech.esper.metrics.instrumentation.InstrumentationHelper;
import com.espertech.esper.supportregression.bean.SupportBean;
import com.espertech.esper.supportregression.bean.SupportBean_S0;
import com.espertech.esper.supportregression.bean.SupportBean_S1;
import com.espertech.esper.supportregression.client.SupportConfigFactory;
import junit.framework.TestCase;
public class TestContextInitTermWithDistinct extends TestCase {
private EPServiceProvider epService;
private SupportUpdateListener listener;
public void setUp()
{
Configuration configuration = SupportConfigFactory.getConfiguration();
configuration.addEventType("SupportBean", SupportBean.class);
configuration.addEventType("SupportBean_S0", SupportBean_S0.class);
configuration.addEventType("SupportBean_S1", SupportBean_S1.class);
epService = EPServiceProviderManager.getDefaultProvider(configuration);
epService.initialize();
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());}
listener = new SupportUpdateListener();
}
public void tearDown() {
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();}
listener = null;
}
public void testInvalid() {
// require stream name assignment using 'as'
tryInvalid("create context MyContext initiated by distinct(theString) SupportBean terminated after 15 seconds",
"Error starting statement: Distinct-expressions require that a stream name is assigned to the stream using 'as' [create context MyContext initiated by distinct(theString) SupportBean terminated after 15 seconds]");
// require stream
tryInvalid("create context MyContext initiated by distinct(a.theString) pattern [a=SupportBean] terminated after 15 seconds",
"Error starting statement: Distinct-expressions require a stream as the initiated-by condition [create context MyContext initiated by distinct(a.theString) pattern [a=SupportBean] terminated after 15 seconds]");
// invalid distinct-clause expression
tryInvalid("create context MyContext initiated by distinct((select * from MyWindow)) SupportBean as sb terminated after 15 seconds",
"Error starting statement: Invalid context distinct-clause expression 'subselect_0': Aggregation, sub-select, previous or prior functions are not supported in this context [create context MyContext initiated by distinct((select * from MyWindow)) SupportBean as sb terminated after 15 seconds]");
// empty list of expressions
tryInvalid("create context MyContext initiated by distinct() SupportBean terminated after 15 seconds",
"Error starting statement: Distinct-expressions have not been provided [create context MyContext initiated by distinct() SupportBean terminated after 15 seconds]");
// non-overlapping context not allowed with distinct
tryInvalid("create context MyContext start distinct(theString) SupportBean end after 15 seconds",
"Incorrect syntax near 'distinct' (a reserved keyword) at line 1 column 31 [create context MyContext start distinct(theString) SupportBean end after 15 seconds]");
}
public void testNullKey() {
runAssertionNullSingleKey();
runAssertionNullKeyMultiKey();
}
public void testDistinctOverlappingSingleKey() {
epService.getEPAdministrator().createEPL(
"create context MyContext " +
" initiated by distinct(s0.theString) SupportBean(intPrimitive = 0) s0" +
" terminated by SupportBean(theString = s0.theString and intPrimitive = 1)");
String[] fields = "theString,longPrimitive,cnt".split(",");
EPStatement stmt = epService.getEPAdministrator().createEPL(
"context MyContext " +
"select theString, longPrimitive, count(*) as cnt from SupportBean(theString = context.s0.theString)");
stmt.addListener(listener);
sendEvent(epService, "A", -1, 10);
sendEvent(epService, "A", 1, 11);
assertFalse(listener.isInvoked());
sendEvent(epService, "A", 0, 12); // allocate context
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"A", 12L, 1L});
sendEvent(epService, "A", 0, 13); // counts towards the existing context, not having a new one
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"A", 13L, 2L});
sendEvent(epService, "A", -1, 14);
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"A", 14L, 3L});
sendEvent(epService, "A", 1, 15); // context termination
sendEvent(epService, "A", -1, 16);
assertFalse(listener.isInvoked());
sendEvent(epService, "A", 0, 17); // allocate context
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{"A", 17L, 1L});
sendEvent(epService, "A", -1, 18);
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{"A", 18L, 2L});
sendEvent(epService, "B", 0, 19); // allocate context
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"B", 19L, 1L});
sendEvent(epService, "B", -1, 20);
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"B", 20L, 2L});
sendEvent(epService, "A", 1, 21); // context termination
sendEvent(epService, "B", 1, 22); // context termination
sendEvent(epService, "A", -1, 23);
sendEvent(epService, "B", -1, 24);
assertFalse(listener.isInvoked());
sendEvent(epService, "A", 0, 25); // allocate context
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"A", 25L, 1L});
sendEvent(epService, "B", 0, 26); // allocate context
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"B", 26L, 1L});
}
public void testDistinctOverlappingMultiKey() {
String epl = "create context MyContext as " +
"initiated by distinct(theString, intPrimitive) SupportBean as sb " +
"terminated SupportBean_S1"; // any S1 ends the contexts
EPStatementObjectModel model = epService.getEPAdministrator().compileEPL(epl);
assertEquals(epl, model.toEPL());
EPStatement stmtContext = epService.getEPAdministrator().create(model);
assertEquals(stmtContext.getText(), model.toEPL());
String[] fields = "id,p00,p01,cnt".split(",");
EPStatement stmt = epService.getEPAdministrator().createEPL(
"context MyContext " +
"select id, p00, p01, count(*) as cnt " +
"from SupportBean_S0(id = context.sb.intPrimitive and p00 = context.sb.theString)");
stmt.addListener(listener);
epService.getEPRuntime().sendEvent(new SupportBean_S0(1, "A"));
epService.getEPRuntime().sendEvent(new SupportBean("A", 1));
assertFalse(listener.isInvoked());
epService.getEPRuntime().sendEvent(new SupportBean_S0(1, "A", "E1"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {1, "A", "E1", 1L});
epService.getEPRuntime().sendEvent(new SupportBean_S0(1, "A", "E2"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {1, "A", "E2", 2L});
epService.getEPRuntime().sendEvent(new SupportBean_S1(-1)); // terminate all
epService.getEPRuntime().sendEvent(new SupportBean_S0(1, "A", "E3"));
epService.getEPRuntime().sendEvent(new SupportBean("A", 1));
epService.getEPRuntime().sendEvent(new SupportBean("B", 2));
epService.getEPRuntime().sendEvent(new SupportBean("B", 1));
assertFalse(listener.isInvoked());
epService.getEPRuntime().sendEvent(new SupportBean_S0(1, "A", "E4"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {1, "A", "E4", 1L});
epService.getEPRuntime().sendEvent(new SupportBean_S0(2, "B", "E5"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {2, "B", "E5", 1L});
epService.getEPRuntime().sendEvent(new SupportBean_S0(1, "B", "E6"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {1, "B", "E6", 1L});
epService.getEPRuntime().sendEvent(new SupportBean_S0(2, "B", "E7"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {2, "B", "E7", 2L});
epService.getEPRuntime().sendEvent(new SupportBean_S1(-1)); // terminate all
epService.getEPRuntime().sendEvent(new SupportBean_S0(2, "B", "E8"));
epService.getEPRuntime().sendEvent(new SupportBean("B", 2));
assertFalse(listener.isInvoked());
epService.getEPRuntime().sendEvent(new SupportBean_S0(2, "B", "E9"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{2, "B", "E9", 1L});
epService.getEPRuntime().sendEvent(new SupportBean_S0(2, "B", "E10"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{2, "B", "E10", 2L});
// destroy context partition, should forget about the distinct key
if (getSpi(epService).isSupportsExtract()) {
getSpi(epService).destroyContextPartitions("MyContext", new ContextPartitionSelectorAll());
epService.getEPRuntime().sendEvent(new SupportBean_S0(2, "B", "E11"));
epService.getEPRuntime().sendEvent(new SupportBean("B", 2));
assertFalse(listener.isInvoked());
epService.getEPRuntime().sendEvent(new SupportBean_S0(2, "B", "E12"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{2, "B", "E12", 1L});
}
}
private void runAssertionNullSingleKey() {
epService.getEPAdministrator().createEPL("create context MyContext initiated by distinct(theString) SupportBean as sb terminated after 24 hours");
EPStatement stmt = epService.getEPAdministrator().createEPL("context MyContext select count(*) as cnt from SupportBean");
stmt.addListener(listener);
epService.getEPRuntime().sendEvent(new SupportBean(null, 10));
assertEquals(1L, listener.assertOneGetNewAndReset().get("cnt"));
epService.getEPRuntime().sendEvent(new SupportBean(null, 20));
assertEquals(2L, listener.assertOneGetNewAndReset().get("cnt"));
epService.getEPRuntime().sendEvent(new SupportBean("A", 30));
assertEquals(2, listener.getAndResetLastNewData().length);
epService.getEPAdministrator().destroyAllStatements();
}
private void runAssertionNullKeyMultiKey() {
epService.getEPAdministrator().createEPL("create context MyContext initiated by distinct(theString, intBoxed, intPrimitive) SupportBean as sb terminated after 100 hours");
EPStatement stmt = epService.getEPAdministrator().createEPL("context MyContext select count(*) as cnt from SupportBean");
stmt.addListener(listener);
sendSBEvent(epService, "A", null, 1);
assertEquals(1L, listener.assertOneGetNewAndReset().get("cnt"));
sendSBEvent(epService, "A", null, 1);
assertEquals(2L, listener.assertOneGetNewAndReset().get("cnt"));
sendSBEvent(epService, "A", 10, 1);
assertEquals(2, listener.getAndResetLastNewData().length);
epService.getEPAdministrator().destroyAllStatements();
}
private static void sendEvent(EPServiceProvider engine, String theString, int intPrimitive, long longPrimitive) {
SupportBean event = new SupportBean(theString, intPrimitive);
event.setLongPrimitive(longPrimitive);
engine.getEPRuntime().sendEvent(event);
}
private void tryInvalid(String epl, String message) {
try {
epService.getEPAdministrator().createEPL(epl);
fail();
}
catch (EPStatementException ex) {
assertEquals(message, ex.getMessage());
}
}
private static void sendSBEvent(EPServiceProvider engine, String string, Integer intBoxed, int intPrimitive) {
SupportBean bean = new SupportBean(string, intPrimitive);
bean.setIntBoxed(intBoxed);
engine.getEPRuntime().sendEvent(bean);
}
private static EPContextPartitionAdminSPI getSpi(EPServiceProvider epService) {
return ((EPContextPartitionAdminSPI) epService.getEPAdministrator().getContextPartitionAdmin());
}
}