/* *************************************************************************************** * 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.scopetest.EPAssertionUtil; import com.espertech.esper.client.scopetest.SupportUpdateListener; import com.espertech.esper.core.context.mgr.ContextManagementService; import com.espertech.esper.core.service.EPServiceProviderSPI; import com.espertech.esper.metrics.instrumentation.InstrumentationHelper; import com.espertech.esper.schedule.SchedulingService; import com.espertech.esper.supportregression.bean.SupportBean; import com.espertech.esper.supportregression.bean.SupportBean_S0; import com.espertech.esper.supportregression.client.SupportConfigFactory; import com.espertech.esper.supportregression.virtualdw.SupportVirtualDW; import com.espertech.esper.supportregression.virtualdw.SupportVirtualDWFactory; import junit.framework.TestCase; public class TestContextLifecycle extends TestCase { private EPServiceProvider epService; private EPServiceProviderSPI spi; public void setUp() { Configuration configuration = SupportConfigFactory.getConfiguration(); configuration.addEventType("SupportBean", SupportBean.class); configuration.addEventType("SupportBean_S0", SupportBean_S0.class); configuration.addPlugInVirtualDataWindow("test", "vdw", SupportVirtualDWFactory.class.getName(), SupportVirtualDW.ITERATE); // configure with iteration epService = EPServiceProviderManager.getDefaultProvider(configuration); epService.initialize(); if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());} spi = (EPServiceProviderSPI) epService; } public void tearDown() { if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();} } public void testSplitStream() throws Exception { String eplOne = "create context CtxSegmentedByTarget partition by theString from SupportBean;" + "@Name('out') context CtxSegmentedByTarget on SupportBean insert into NewSupportBean select * where intPrimitive = 100;"; epService.getEPAdministrator().getDeploymentAdmin().parseDeploy(eplOne); SupportUpdateListener listener = new SupportUpdateListener(); epService.getEPAdministrator().createEPL("select * from NewSupportBean").addListener(listener); epService.getEPRuntime().sendEvent(new SupportBean("E1", 1)); assertFalse(listener.getAndClearIsInvoked()); epService.getEPRuntime().sendEvent(new SupportBean("E1", 100)); assertTrue(listener.getAndClearIsInvoked()); epService.getEPAdministrator().destroyAllStatements(); listener.reset(); // test with subquery String[] fields = "mymax".split(","); String eplTwo = "create context CtxSegmentedByTarget partition by theString from SupportBean;" + "context CtxSegmentedByTarget create window NewEvent#unique(theString) as SupportBean;" + "@Name('out') context CtxSegmentedByTarget on SupportBean " + "insert into NewEvent select * where intPrimitive = 100 " + "insert into NewEventTwo select (select max(intPrimitive) from NewEvent) as mymax " + "output all;"; epService.getEPAdministrator().getDeploymentAdmin().parseDeploy(eplTwo); epService.getEPAdministrator().createEPL("select * from NewEventTwo").addListener(listener); epService.getEPRuntime().sendEvent(new SupportBean("E1", 1)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {null}); epService.getEPRuntime().sendEvent(new SupportBean("E1", 100)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {null}); epService.getEPRuntime().sendEvent(new SupportBean("E1", 0)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {100}); } public void testVirtualDataWindow() { SupportVirtualDWFactory.getWindows().clear(); SupportVirtualDWFactory.setDestroyed(false); epService.getEPAdministrator().createEPL("create context CtxSegmented as partition by theString from SupportBean"); epService.getEPAdministrator().createEPL("context CtxSegmented create window TestVDWWindow.test:vdw() as SupportBean"); epService.getEPAdministrator().createEPL("select * from TestVDWWindow"); epService.getEPRuntime().sendEvent(new SupportBean("E1", 1)); epService.getEPRuntime().sendEvent(new SupportBean("E2", 2)); assertEquals(2, SupportVirtualDWFactory.getWindows().size()); // Independent windows for independent contexts epService.getEPAdministrator().destroyAllStatements(); for (SupportVirtualDW vdw : SupportVirtualDWFactory.getWindows()) { assertTrue(vdw.isDestroyed()); } assertTrue(SupportVirtualDWFactory.isDestroyed()); } public void testNWOtherContextOnExpr() { epService.getEPAdministrator().createEPL("create context NineToFive as start (0, 9, *, *, *) end (0, 17, *, *, *)"); epService.getEPAdministrator().createEPL("create context TenToFive as start (0, 10, *, *, *) end (0, 17, *, *, *)"); // Trigger not in context EPStatement stmtNamedWindow = epService.getEPAdministrator().createEPL("context NineToFive create window MyWindow#keepall as SupportBean"); try { epService.getEPAdministrator().createEPL("on SupportBean_S0 s0 merge MyWindow mw when matched then update set intPrimitive = 1"); fail(); } catch (EPStatementException ex) { assertEquals("Error starting statement: Cannot create on-trigger expression: Named window 'MyWindow' was declared with context 'NineToFive', please declare the same context name [on SupportBean_S0 s0 merge MyWindow mw when matched then update set intPrimitive = 1]", ex.getMessage()); } // Trigger in different context try { epService.getEPAdministrator().createEPL("context TenToFive on SupportBean_S0 s0 merge MyWindow mw when matched then update set intPrimitive = 1"); fail(); } catch (EPStatementException ex) { assertEquals("Error starting statement: Cannot create on-trigger expression: Named window 'MyWindow' was declared with context 'NineToFive', please use the same context instead [context TenToFive on SupportBean_S0 s0 merge MyWindow mw when matched then update set intPrimitive = 1]", ex.getMessage()); } // Named window not in context, trigger in different context stmtNamedWindow.destroy(); epService.getEPAdministrator().createEPL("create window MyWindow#keepall as SupportBean"); try { epService.getEPAdministrator().createEPL("context TenToFive on SupportBean_S0 s0 merge MyWindow mw when matched then update set intPrimitive = 1"); fail(); } catch (EPStatementException ex) { assertEquals("Error starting statement: Cannot create on-trigger expression: Named window 'MyWindow' was declared with context 'null', please use the same context instead [context TenToFive on SupportBean_S0 s0 merge MyWindow mw when matched then update set intPrimitive = 1]", ex.getMessage()); } } public void testLifecycle() { String epl = "@Name('context') create context NineToFive as start (0, 9, *, *, *) end (0, 17, *, *, *)"; ContextManagementService ctxMgmtService = spi.getContextManagementService(); SchedulingService schedulingService = spi.getSchedulingService(); assertEquals(0, ctxMgmtService.getContextCount()); assertEquals(0, schedulingService.getScheduleHandleCount()); // create and destroy EPStatement stmtContext = epService.getEPAdministrator().createEPL(epl); assertEquals(1, ctxMgmtService.getContextCount()); assertEquals(0, schedulingService.getScheduleHandleCount()); stmtContext.destroy(); assertEquals(0, ctxMgmtService.getContextCount()); // create context, create statement, destroy statement, destroy context stmtContext = epService.getEPAdministrator().createEPL(epl); assertEquals(1, ctxMgmtService.getContextCount()); EPStatement stmt = epService.getEPAdministrator().createEPL("@Name('C') context NineToFive select * from SupportBean"); assertEquals(1, schedulingService.getScheduleHandleCount()); stmt.destroy(); assertEquals(0, schedulingService.getScheduleHandleCount()); stmtContext.destroy(); assertEquals(0, ctxMgmtService.getContextCount()); // create same context epService.getEPAdministrator().createEPL(epl); epService.getEPAdministrator().createEPL("@Name('C') context NineToFive select * from SupportBean"); epService.getEPAdministrator().createEPL("@Name('D') context NineToFive select * from SupportBean"); epService.getEPAdministrator().destroyAllStatements(); assertEquals(0, ctxMgmtService.getContextCount()); assertEquals(0, schedulingService.getScheduleHandleCount()); } public void testInvalid() { // same context twice String eplCreateCtx = "create context NineToFive as start (0, 9, *, *, *) end (0, 17, *, *, *)"; EPStatement stmtContext = epService.getEPAdministrator().createEPL(eplCreateCtx); tryInvalid(eplCreateCtx, "Error starting statement: Context by name 'NineToFive' already exists ["); // still in use epService.getEPAdministrator().createEPL("context NineToFive select * from SupportBean"); stmtContext.destroy(); tryInvalid(eplCreateCtx, "Error starting statement: Context by name 'NineToFive' is still referenced by statements and may not be changed"); // not found tryInvalid("context EightToSix select * from SupportBean", "Error starting statement: Context by name 'EightToSix' has not been declared ["); // test update: update is not allowed as it is processed out-of-context by runtime epService.getEPAdministrator().createEPL("insert into ABCStream select * from SupportBean"); epService.getEPAdministrator().createEPL("@Name('context') create context SegmentedByAString partition by theString from SupportBean"); try { epService.getEPAdministrator().createEPL("context SegmentedByAString update istream ABCStream set intPrimitive = (select id from SupportBean_S0#lastevent) where intPrimitive < 0"); fail(); } catch (EPStatementException ex) { assertEquals("Error starting statement: Update IStream is not supported in conjunction with a context [context SegmentedByAString update istream ABCStream set intPrimitive = (select id from SupportBean_S0#lastevent) where intPrimitive < 0]", ex.getMessage()); } // context declaration for create-context epService.getEPAdministrator().createEPL("create context ABC start @now end after 5 seconds"); tryInvalid("context ABC create context DEF start @now end after 5 seconds", "Error starting statement: A create-context statement cannot itself be associated to a context, please declare a nested context instead [context ABC create context DEF start @now end after 5 seconds]"); } private void tryInvalid(String epl, String expected) { try { epService.getEPAdministrator().createEPL(epl); fail(); } catch (EPStatementException ex) { if (!ex.getMessage().startsWith(expected)) { throw new RuntimeException("Expected/Received:\n" + expected + "\n" + ex.getMessage() + "\n"); } assertTrue(expected.trim().length() != 0); } } }