/* *************************************************************************************** * 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.client; import com.espertech.esper.client.*; 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.EPServiceProviderSPI; import com.espertech.esper.metrics.instrumentation.InstrumentationHelper; import com.espertech.esper.plugin.PlugInAggregationMultiFunctionDeclarationContext; import com.espertech.esper.plugin.PlugInAggregationMultiFunctionStateContext; import com.espertech.esper.plugin.PlugInAggregationMultiFunctionValidationContext; import com.espertech.esper.supportregression.bean.SupportBean; import com.espertech.esper.supportregression.client.SupportConfigFactory; import com.espertech.esper.util.support.SupportEventTypeAssertionEnum; import com.espertech.esper.util.support.SupportEventTypeAssertionUtil; import junit.framework.TestCase; import java.util.Collection; public class TestAggregationMultiFunctionPlugIn extends TestCase { private EPServiceProvider epService; private SupportUpdateListener listener; public void setUp() { Configuration configuration = SupportConfigFactory.getConfiguration(); ConfigurationPlugInAggregationMultiFunction config = new ConfigurationPlugInAggregationMultiFunction(SupportAggMFFunc.getFunctionNames(), SupportAggMFFactory.class.getName()); configuration.addPlugInAggregationMultiFunction(config); epService = EPServiceProviderManager.getDefaultProvider(configuration); epService.initialize(); if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());} epService.getEPAdministrator().getConfiguration().addEventType(SupportBean.class); listener = new SupportUpdateListener(); } public void tearDown() { if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();} listener = null; } public void testDifferentReturnTypes() { // test scalar only String[] fieldsScalar = "c0,c1".split(","); String eplScalar = "select ss(theString) as c0, ss(intPrimitive) as c1 from SupportBean"; EPStatement stmtScalar = epService.getEPAdministrator().createEPL(eplScalar); stmtScalar.addListener(listener); Object[][] expectedScalar = new Object[][]{{"c0", String.class, null, null}, {"c1", int.class, null, null}}; SupportEventTypeAssertionUtil.assertEventTypeProperties(expectedScalar, stmtScalar.getEventType(), SupportEventTypeAssertionEnum.getSetWithFragment()); epService.getEPRuntime().sendEvent(new SupportBean("E1", 1)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fieldsScalar, new Object[]{"E1", 1}); epService.getEPRuntime().sendEvent(new SupportBean("E2", 2)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fieldsScalar, new Object[]{"E2", 2}); stmtScalar.destroy(); // test scalar-array only String[] fieldsScalarArray = "c0,c1,c2,c3".split(","); String eplScalarArray = "select " + "sa(theString) as c0, " + "sa(intPrimitive) as c1, " + "sa(theString).allOf(v => v = 'E1') as c2, " + "sa(intPrimitive).allOf(v => v = 1) as c3 " + "from SupportBean"; EPStatement stmtScalarArray = epService.getEPAdministrator().createEPL(eplScalarArray); stmtScalarArray.addListener(listener); Object[][] expectedScalarArray = new Object[][]{ {"c0", String[].class, null, null}, {"c1", int[].class, null, null}, {"c2", Boolean.class, null, null}, {"c3", Boolean.class, null, null}, }; SupportEventTypeAssertionUtil.assertEventTypeProperties(expectedScalarArray, stmtScalarArray.getEventType(), SupportEventTypeAssertionEnum.getSetWithFragment()); epService.getEPRuntime().sendEvent(new SupportBean("E1", 1)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fieldsScalarArray, new Object[]{ new String[] {"E1"}, new int[] {1}, true, true}); epService.getEPRuntime().sendEvent(new SupportBean("E2", 2)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fieldsScalarArray, new Object[]{ new String[] {"E1", "E2"}, new int[] {1, 2}, false, false}); stmtScalarArray.destroy(); // test scalar-collection only String[] fieldsScalarColl = "c2,c3".split(","); String eplScalarColl = "select " + "sc(theString) as c0, " + "sc(intPrimitive) as c1, " + "sc(theString).allOf(v => v = 'E1') as c2, " + "sc(intPrimitive).allOf(v => v = 1) as c3 " + "from SupportBean"; EPStatement stmtScalarColl = epService.getEPAdministrator().createEPL(eplScalarColl); stmtScalarColl.addListener(listener); Object[][] expectedScalarColl = new Object[][]{ {"c0", Collection.class, null, null}, {"c1", Collection.class, null, null}, {"c2", Boolean.class, null, null}, {"c3", Boolean.class, null, null}, }; SupportEventTypeAssertionUtil.assertEventTypeProperties(expectedScalarColl, stmtScalarColl.getEventType(), SupportEventTypeAssertionEnum.getSetWithFragment()); epService.getEPRuntime().sendEvent(new SupportBean("E1", 1)); EPAssertionUtil.assertEqualsExactOrder(new Object[] {"E1"}, (Collection)listener.assertOneGetNew().get("c0")); EPAssertionUtil.assertEqualsExactOrder(new Object[] {1}, (Collection)listener.assertOneGetNew().get("c1")); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fieldsScalarColl, new Object[]{true, true}); epService.getEPRuntime().sendEvent(new SupportBean("E2", 2)); EPAssertionUtil.assertEqualsExactOrder(new Object[] {"E1", "E2"}, (Collection)listener.assertOneGetNew().get("c0")); EPAssertionUtil.assertEqualsExactOrder(new Object[] {1, 2}, (Collection)listener.assertOneGetNew().get("c1")); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fieldsScalarColl, new Object[]{false, false}); stmtScalarColl.destroy(); // test single-event return String[] fieldsSingleEvent = "c0,c1,c2,c3,c4".split(","); String eplSingleEvent = "select " + "se1() as c0, " + "se1().allOf(v => v.theString = 'E1') as c1, " + "se1().allOf(v => v.intPrimitive = 1) as c2, " + "se1().theString as c3, " + "se1().intPrimitive as c4 " + "from SupportBean"; EPStatement stmtSingleEvent = epService.getEPAdministrator().createEPL(eplSingleEvent); stmtSingleEvent.addListener(listener); Object[][] expectedSingleEvent = new Object[][]{ {"c0", SupportBean.class, "SupportBean", false}, {"c1", Boolean.class, null, null}, {"c2", Boolean.class, null, null}, {"c3", String.class, null, null}, {"c4", Integer.class, null, null}, }; SupportEventTypeAssertionUtil.assertEventTypeProperties(expectedSingleEvent, stmtSingleEvent.getEventType(), SupportEventTypeAssertionEnum.getSetWithFragment()); SupportBean eventOne = new SupportBean("E1", 1); epService.getEPRuntime().sendEvent(eventOne); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fieldsSingleEvent, new Object[]{eventOne, true, true, "E1", 1}); SupportBean eventTwo = new SupportBean("E2", 2); epService.getEPRuntime().sendEvent(eventTwo); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fieldsSingleEvent, new Object[]{eventTwo, false, false, "E2", 2}); stmtSingleEvent.destroy(); // test single-event return String[] fieldsEnumEvent = "c0,c1,c2".split(","); String eplEnumEvent = "select " + "ee() as c0, " + "ee().allOf(v => v.theString = 'E1') as c1, " + "ee().allOf(v => v.intPrimitive = 1) as c2 " + "from SupportBean"; EPStatement stmtEnumEvent = epService.getEPAdministrator().createEPL(eplEnumEvent); stmtEnumEvent.addListener(listener); Object[][] expectedEnumEvent = new Object[][]{ {"c0", SupportBean[].class, "SupportBean", true}, {"c1", Boolean.class, null, null}, {"c2", Boolean.class, null, null} }; SupportEventTypeAssertionUtil.assertEventTypeProperties(expectedEnumEvent, stmtEnumEvent.getEventType(), SupportEventTypeAssertionEnum.getSetWithFragment()); SupportBean eventEnumOne = new SupportBean("E1", 1); epService.getEPRuntime().sendEvent(eventEnumOne); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fieldsEnumEvent, new Object[]{new SupportBean[] {eventEnumOne}, true, true}); SupportBean eventEnumTwo = new SupportBean("E2", 2); epService.getEPRuntime().sendEvent(eventEnumTwo); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fieldsEnumEvent, new Object[]{new SupportBean[] {eventEnumOne, eventEnumTwo}, false, false}); } public void testSameProviderGroupedReturnSingleEvent() throws Exception { String epl = "select se1() as c0, se2() as c1 from SupportBean#keepall group by theString"; // test regular SupportAggMFFactory.reset(); SupportAggMFHandler.reset(); SupportAggMFFactorySingleEvent.reset(); EPStatement stmt = epService.getEPAdministrator().createEPL(epl); runAssertion(stmt); // test SODA EPStatementObjectModel model = epService.getEPAdministrator().compileEPL(epl); SupportAggMFFactory.reset(); SupportAggMFHandler.reset(); SupportAggMFFactorySingleEvent.reset(); assertEquals(epl, model.toEPL()); EPStatement stmtModel = epService.getEPAdministrator().create(model); assertEquals(epl, stmtModel.getText()); runAssertion(stmtModel); } private void runAssertion(EPStatement stmt) { stmt.addListener(listener); String[] fields = "c0,c1".split(","); for (String prop : fields) { assertEquals(SupportBean.class, stmt.getEventType().getPropertyDescriptor(prop).getPropertyType()); assertEquals(true, stmt.getEventType().getPropertyDescriptor(prop).isFragment()); assertEquals("SupportBean", stmt.getEventType().getFragmentType(prop).getFragmentType().getName()); } // there should be just 1 factory instance for all of the registered functions for this statement assertEquals(1, SupportAggMFFactory.getFactories().size()); assertEquals(2, SupportAggMFFactory.getFunctionDeclContexts().size()); for (int i = 0; i < 2; i++) { PlugInAggregationMultiFunctionDeclarationContext contextDecl = SupportAggMFFactory.getFunctionDeclContexts().get(i); assertEquals(i == 0 ? "se1" : "se2", contextDecl.getFunctionName()); assertEquals(EPServiceProviderSPI.DEFAULT_ENGINE_URI, contextDecl.getEngineURI()); assertFalse(contextDecl.isDistinct()); assertNotNull(contextDecl.getConfiguration()); PlugInAggregationMultiFunctionValidationContext contextValid = SupportAggMFFactory.getFunctionHandlerValidationContexts().get(i); assertEquals(i == 0 ? "se1" : "se2", contextValid.getFunctionName()); assertEquals(EPServiceProviderSPI.DEFAULT_ENGINE_URI, contextValid.getEngineURI()); assertNotNull(contextValid.getParameterExpressions()); assertNotNull(contextValid.getAllParameterExpressions()); assertNotNull(contextValid.getConfig()); assertNotNull(contextValid.getEventTypes()); assertNotNull(contextValid.getValidationContext()); assertNotNull(contextValid.getStatementName()); } assertEquals(2, SupportAggMFHandler.getProviderKeys().size()); assertEquals(2, SupportAggMFHandler.getAccessors().size()); assertEquals(1, SupportAggMFHandler.getProviderFactories().size()); assertEquals(0, SupportAggMFFactorySingleEvent.getStateContexts().size()); // group 1 SupportBean eventOne = new SupportBean("E1", 1); epService.getEPRuntime().sendEvent(eventOne); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{eventOne, eventOne}); assertEquals(1, SupportAggMFFactorySingleEvent.getStateContexts().size()); PlugInAggregationMultiFunctionStateContext context = SupportAggMFFactorySingleEvent.getStateContexts().get(0); assertEquals("E1", context.getGroupKey()); // group 2 SupportBean eventTwo = new SupportBean("E2", 2); epService.getEPRuntime().sendEvent(eventTwo); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{eventTwo, eventTwo}); assertEquals(2, SupportAggMFFactorySingleEvent.getStateContexts().size()); stmt.destroy(); } public void testInvalid() { // add overlapping config with regular agg function try { epService.getEPAdministrator().getConfiguration().addPlugInAggregationFunctionFactory(SupportAggMFFunc.SCALAR.getName(), "somefactory"); fail(); } catch (ConfigurationException ex) { assertEquals("Aggregation multi-function by name 'ss' is already defined", ex.getMessage()); } // add overlapping config with regular agg function try { epService.getEPAdministrator().getConfiguration().addPlugInSingleRowFunction(SupportAggMFFunc.SCALAR.getName(), "somefactory", "somename"); fail(); } catch (ConfigurationException ex) { assertEquals("Aggregation multi-function by name 'ss' is already defined", ex.getMessage()); } // test over lapping with another multi-function ConfigurationPlugInAggregationMultiFunction config = new ConfigurationPlugInAggregationMultiFunction("thefunction".split(","), SupportAggMFFactory.class.getName()); epService.getEPAdministrator().getConfiguration().addPlugInAggregationMultiFunction(config); try { ConfigurationPlugInAggregationMultiFunction configTwo = new ConfigurationPlugInAggregationMultiFunction("xyz,gmbh,thefunction".split(","), TestAggregationFunctionPlugIn.class.getName()); epService.getEPAdministrator().getConfiguration().addPlugInAggregationMultiFunction(configTwo); fail(); } catch (ConfigurationException ex) { assertEquals("Aggregation multi-function by name 'thefunction' is already defined", ex.getMessage()); } // test invalid class name try { ConfigurationPlugInAggregationMultiFunction configTwo = new ConfigurationPlugInAggregationMultiFunction("thefunction2".split(","), "x y z"); epService.getEPAdministrator().getConfiguration().addPlugInAggregationMultiFunction(configTwo); fail(); } catch (ConfigurationException ex) { assertEquals("Invalid class name for aggregation multi-function factory 'x y z'", ex.getMessage()); } } }