/* * ************************************************************************************* * Copyright (C) 2008 EsperTech, Inc. All rights reserved. * * http://esper.codehaus.org * * 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.epl; import com.espertech.esper.client.*; import com.espertech.esper.client.scopetest.EPAssertionUtil; import com.espertech.esper.client.scopetest.SupportUpdateListener; import com.espertech.esper.collection.Pair; import com.espertech.esper.support.bean.*; import com.espertech.esper.support.client.SupportConfigFactory; import com.espertech.esper.support.epl.SupportStaticMethodLib; import junit.framework.TestCase; import java.io.Serializable; import java.util.HashMap; import java.util.Map; public class TestInsertIntoTransposeStream extends TestCase { private EPServiceProvider epService; private SupportUpdateListener listener; public void setUp() { Configuration configuration = SupportConfigFactory.getConfiguration(); epService = EPServiceProviderManager.getDefaultProvider(configuration); epService.initialize(); listener = new SupportUpdateListener(); } protected void tearDown() throws Exception { listener = null; } public void testTransposeFunctionToStreamWithProps() { epService.getEPAdministrator().getConfiguration().addEventType(SupportBean.class); epService.getEPAdministrator().getConfiguration().addPlugInSingleRowFunction("custom", SupportStaticMethodLib.class.getName(), "makeSupportBean"); String stmtTextOne = "insert into MyStream select 1 as dummy, transpose(custom('O' || theString, 10)) from SupportBean(theString like 'I%')"; epService.getEPAdministrator().createEPL(stmtTextOne); String stmtTextTwo = "select * from MyStream"; EPStatement stmt = epService.getEPAdministrator().createEPL(stmtTextTwo); stmt.addListener(listener); EventType type = stmt.getEventType(); assertEquals(Pair.class, type.getUnderlyingType()); epService.getEPRuntime().sendEvent(new SupportBean("I1", 1)); EventBean result = listener.assertOneGetNewAndReset(); Pair underlying = (Pair) result.getUnderlying(); EPAssertionUtil.assertProps(result, "dummy,theString,intPrimitive".split(","), new Object[]{1, "OI1", 10}); assertEquals("OI1", ((SupportBean) underlying.getFirst()).getTheString()); } public void testTransposeFunctionToStream() { epService.getEPAdministrator().getConfiguration().addEventType(SupportBean.class); epService.getEPAdministrator().getConfiguration().addPlugInSingleRowFunction("custom", SupportStaticMethodLib.class.getName(), "makeSupportBean"); String stmtTextOne = "insert into OtherStream select transpose(custom('O' || theString, 10)) from SupportBean(theString like 'I%')"; epService.getEPAdministrator().createEPL(stmtTextOne); String stmtTextTwo = "select * from OtherStream(theString like 'O%')"; EPStatement stmt = epService.getEPAdministrator().createEPL(stmtTextTwo); stmt.addListener(listener); EventType type = stmt.getEventType(); assertEquals(SupportBean.class, type.getUnderlyingType()); epService.getEPRuntime().sendEvent(new SupportBean("I1", 1)); EventBean result = listener.assertOneGetNewAndReset(); EPAssertionUtil.assertProps(result, "theString,intPrimitive".split(","), new Object[]{"OI1", 10}); assertEquals("OI1", ((SupportBean) result.getUnderlying()).getTheString()); } public void testTransposeSingleColumnInsert() { epService.getEPAdministrator().getConfiguration().addEventType(SupportBean.class); epService.getEPAdministrator().getConfiguration().addEventType(SupportBeanNumeric.class); epService.getEPAdministrator().getConfiguration().addPlugInSingleRowFunction("customOne", SupportStaticMethodLib.class.getName(), "makeSupportBean"); epService.getEPAdministrator().getConfiguration().addPlugInSingleRowFunction("customTwo", SupportStaticMethodLib.class.getName(), "makeSupportBeanNumeric"); // with transpose and same input and output String stmtTextOne = "insert into SupportBean select transpose(customOne('O' || theString, 10)) from SupportBean(theString like 'I%')"; EPStatement stmtOne = epService.getEPAdministrator().createEPL(stmtTextOne); assertEquals(SupportBean.class, stmtOne.getEventType().getUnderlyingType()); stmtOne.addListener(listener); epService.getEPRuntime().sendEvent(new SupportBean("I1", 1)); EventBean resultOne = listener.assertOneGetNewAndReset(); EPAssertionUtil.assertProps(resultOne, "theString,intPrimitive".split(","), new Object[]{"OI1", 10}); assertEquals("OI1", ((SupportBean) resultOne.getUnderlying()).getTheString()); stmtOne.destroy(); // with transpose but different input and output (also test ignore column name) String stmtTextTwo = "insert into SupportBeanNumeric select transpose(customTwo(intPrimitive, intPrimitive+1)) as col1 from SupportBean(theString like 'I%')"; EPStatement stmtTwo = epService.getEPAdministrator().createEPL(stmtTextTwo); assertEquals(SupportBeanNumeric.class, stmtTwo.getEventType().getUnderlyingType()); stmtTwo.addListener(listener); epService.getEPRuntime().sendEvent(new SupportBean("I2", 10)); EventBean resultTwo = listener.assertOneGetNewAndReset(); EPAssertionUtil.assertProps(resultTwo, "intOne,intTwo".split(","), new Object[]{10, 11}); assertEquals(11, (int) ((SupportBeanNumeric) resultTwo.getUnderlying()).getIntTwo()); stmtTwo.destroy(); // invalid wrong-bean target try { epService.getEPAdministrator().createEPL("insert into SupportBeanNumeric select transpose(customOne('O', 10)) from SupportBean"); fail(); } catch (EPStatementException ex) { assertEquals("Error starting statement: Expression-returned event type 'SupportBean' with underlying type 'com.espertech.esper.support.bean.SupportBean' cannot be converted target event type 'SupportBeanNumeric' with underlying type 'com.espertech.esper.support.bean.SupportBeanNumeric' [insert into SupportBeanNumeric select transpose(customOne('O', 10)) from SupportBean]", ex.getMessage()); } // invalid additional properties try { epService.getEPAdministrator().createEPL("insert into SupportBean select 1 as dummy, transpose(customOne('O', 10)) from SupportBean"); fail(); } catch (EPStatementException ex) { assertEquals("Error starting statement: Cannot transpose additional properties in the select-clause to target event type 'SupportBean' with underlying type 'com.espertech.esper.support.bean.SupportBean', the transpose function must occur alone in the select clause [insert into SupportBean select 1 as dummy, transpose(customOne('O', 10)) from SupportBean]", ex.getMessage()); } // invalid occurs twice try { epService.getEPAdministrator().createEPL("insert into SupportBean select transpose(customOne('O', 10)), transpose(customOne('O', 11)) from SupportBean"); fail(); } catch (EPStatementException ex) { assertEquals("Error starting statement: A column name must be supplied for all but one stream if multiple streams are selected via the stream.* notation [insert into SupportBean select transpose(customOne('O', 10)), transpose(customOne('O', 11)) from SupportBean]", ex.getMessage()); } // invalid wrong-type target try { epService.getEPAdministrator().getConfiguration().addEventType("SomeOtherStream", new HashMap<String, Object>()); epService.getEPAdministrator().createEPL("insert into SomeOtherStream select transpose(customOne('O', 10)) from SupportBean"); fail(); } catch (EPStatementException ex) { assertEquals("Error starting statement: Event type named 'SomeOtherStream' has already been declared with differing column name or type information: Type 'SomeOtherStream' is not compatible [insert into SomeOtherStream select transpose(customOne('O', 10)) from SupportBean]", ex.getMessage()); } // invalid two parameters try { epService.getEPAdministrator().createEPL("select transpose(customOne('O', 10), customOne('O', 10)) from SupportBean"); fail(); } catch (EPStatementException ex) { assertEquals("Error starting statement: The transpose function requires a single parameter expression [select transpose(customOne('O', 10), customOne('O', 10)) from SupportBean]", ex.getMessage()); } // test not a top-level function or used in where-clause (possible but not useful) epService.getEPAdministrator().createEPL("select * from SupportBean where transpose(customOne('O', 10)) is not null"); epService.getEPAdministrator().createEPL("select transpose(customOne('O', 10)) is not null from SupportBean"); } public void testTransposeEventJoinMap() { Map<String, Object> metadata = makeMap(new Object[][] {{"id", String.class}}); epService.getEPAdministrator().getConfiguration().addEventType("AEvent", metadata); epService.getEPAdministrator().getConfiguration().addEventType("BEvent", metadata); String stmtTextOne = "insert into MyStream select a, b from AEvent.win:keepall() as a, BEvent.win:keepall() as b"; epService.getEPAdministrator().createEPL(stmtTextOne); String stmtTextTwo = "select a.id, b.id from MyStream"; EPStatement stmt = epService.getEPAdministrator().createEPL(stmtTextTwo); stmt.addListener(listener); Map<String, Object> eventOne = makeMap(new Object[][] {{"id", "A1"}}); Map<String, Object> eventTwo = makeMap(new Object[][] {{"id", "B1"}}); epService.getEPRuntime().sendEvent(eventOne, "AEvent"); epService.getEPRuntime().sendEvent(eventTwo, "BEvent"); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), "a.id,b.id".split(","), new Object[]{"A1", "B1"}); } public void testTransposeEventJoinPOJO() { epService.getEPAdministrator().getConfiguration().addEventType("AEvent", SupportBean_A.class); epService.getEPAdministrator().getConfiguration().addEventType("BEvent", SupportBean_B.class); String stmtTextOne = "insert into MyStream select a.* as a, b.* as b from AEvent.win:keepall() as a, BEvent.win:keepall() as b"; epService.getEPAdministrator().createEPL(stmtTextOne); String stmtTextTwo = "select a.id, b.id from MyStream"; EPStatement stmt = epService.getEPAdministrator().createEPL(stmtTextTwo); stmt.addListener(listener); epService.getEPRuntime().sendEvent(new SupportBean_A("A1")); epService.getEPRuntime().sendEvent(new SupportBean_B("B1")); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), "a.id,b.id".split(","), new Object[]{"A1", "B1"}); } public void testTransposePOJOPropertyStream() { epService.getEPAdministrator().getConfiguration().addEventType("Complex", SupportBeanComplexProps.class); String stmtTextOne = "insert into MyStream select nested as inneritem from Complex"; epService.getEPAdministrator().createEPL(stmtTextOne); String stmtTextTwo = "select inneritem.nestedValue as result from MyStream"; EPStatement stmt = epService.getEPAdministrator().createEPL(stmtTextTwo); stmt.addListener(listener); epService.getEPRuntime().sendEvent(SupportBeanComplexProps.makeDefaultBean()); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), "result".split(","), new Object[]{"nestedValue"}); } public void testInvalidTranspose() { Map<String, Object> metadata = makeMap(new Object[][] { {"nested", makeMap(new Object[][] {{"nestedValue", String.class}}) } }); epService.getEPAdministrator().getConfiguration().addEventType("Complex", metadata); String stmtTextOne = "insert into MyStream select nested as inneritem from Complex"; epService.getEPAdministrator().createEPL(stmtTextOne); try { String stmtTextTwo = "select inneritem.nestedValue as result from MyStream"; epService.getEPAdministrator().createEPL(stmtTextTwo); } catch (Exception ex) { assertEquals("Error starting statement: Failed to resolve property 'inneritem.nestedValue' to a stream or nested property in a stream [select inneritem.nestedValue as result from MyStream]", ex.getMessage()); } // test invalid unwrap-properties epService.getEPAdministrator().getConfiguration().addEventType(E1.class); epService.getEPAdministrator().getConfiguration().addEventType(E2.class); epService.getEPAdministrator().getConfiguration().addEventType(EnrichedE2.class); try { epService.getEPAdministrator().createEPL("@Resilient insert into EnrichedE2 " + "select e2.* as event, e1.otherId as playerId " + "from E1.win:length(20) as e1, E2.win:length(1) as e2 " + "where e1.id = e2.id "); } catch (Exception ex) { assertEquals("Error starting statement: The 'e2.* as event' syntax is not allowed when inserting into an existing bean event type, use the 'e2 as event' syntax instead [@Resilient insert into EnrichedE2 select e2.* as event, e1.otherId as playerId from E1.win:length(20) as e1, E2.win:length(1) as e2 where e1.id = e2.id ]", ex.getMessage()); } } private Map<String, Object> makeMap(Object[][] entries) { Map result = new HashMap<String, Object>(); for (Object[] entry : entries) { result.put(entry[0], entry[1]); } return result; } public static class E1 implements Serializable { private final String id; private final String otherId; public E1(String id, String otherId) { this.id = id; this.otherId = otherId; } public String getId() { return id; } public String getOtherId() { return otherId; } } public static class E2 implements Serializable { private final String id; private final String value; public E2(String id, String value) { this.id = id; this.value = value; } public String getId() { return id; } public String getValue() { return value; } } public static class EnrichedE2 implements Serializable { private final E2 event; private final String otherId; public EnrichedE2(E2 event, String playerId) { this.event = event; this.otherId = playerId; } public E2 getEvent() { return event; } public String getOtherId() { return otherId; } } }