/* * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.wso2.siddhi.core.stream.event; import org.junit.Assert; import org.junit.Test; import org.wso2.siddhi.core.config.ExecutionPlanContext; import org.wso2.siddhi.core.config.SiddhiContext; import org.wso2.siddhi.core.event.Event; import org.wso2.siddhi.core.event.SiddhiEventFactory; import org.wso2.siddhi.core.event.state.MetaStateEvent; import org.wso2.siddhi.core.event.stream.MetaStreamEvent; import org.wso2.siddhi.core.event.stream.StreamEvent; import org.wso2.siddhi.core.event.stream.StreamEventFactory; import org.wso2.siddhi.core.event.stream.StreamEventPool; import org.wso2.siddhi.core.event.stream.converter.SelectiveStreamEventConverter; import org.wso2.siddhi.core.event.stream.converter.SimpleStreamEventConverter; import org.wso2.siddhi.core.event.stream.converter.StreamEventConverter; import org.wso2.siddhi.core.event.stream.converter.StreamEventConverterFactory; import org.wso2.siddhi.core.event.stream.converter.ZeroStreamEventConverter; import org.wso2.siddhi.core.exception.OperationNotSupportedException; import org.wso2.siddhi.core.executor.ConstantExpressionExecutor; import org.wso2.siddhi.core.executor.ExpressionExecutor; import org.wso2.siddhi.core.executor.VariableExpressionExecutor; import org.wso2.siddhi.core.executor.condition.AndConditionExpressionExecutor; import org.wso2.siddhi.core.executor.condition.compare.greaterthan.GreaterThanCompareConditionExpressionExecutorIntInt; import org.wso2.siddhi.core.executor.condition.compare.lessthan.LessThanCompareConditionExpressionExecutorFloatFloat; import org.wso2.siddhi.core.executor.math.add.AddExpressionExecutorFloat; import org.wso2.siddhi.core.query.QueryRuntime; import org.wso2.siddhi.core.query.input.stream.single.SingleStreamRuntime; import org.wso2.siddhi.core.stream.input.source.Source; import org.wso2.siddhi.core.stream.output.sink.Sink; import org.wso2.siddhi.core.table.Table; import org.wso2.siddhi.core.util.ElementIdGenerator; import org.wso2.siddhi.core.util.SiddhiConstants; import org.wso2.siddhi.core.util.lock.LockSynchronizer; import org.wso2.siddhi.core.util.parser.QueryParser; import org.wso2.siddhi.core.util.parser.helper.QueryParserHelper; import org.wso2.siddhi.core.util.snapshot.SnapshotService; import org.wso2.siddhi.core.window.Window; import org.wso2.siddhi.query.api.annotation.Annotation; import org.wso2.siddhi.query.api.definition.AbstractDefinition; import org.wso2.siddhi.query.api.definition.Attribute; import org.wso2.siddhi.query.api.definition.StreamDefinition; import org.wso2.siddhi.query.api.execution.query.Query; import org.wso2.siddhi.query.api.execution.query.input.stream.InputStream; import org.wso2.siddhi.query.api.execution.query.selection.Selector; import org.wso2.siddhi.query.api.expression.Expression; import org.wso2.siddhi.query.api.expression.condition.Compare; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; public class EventTestCase { @Test public void testEventCreation() { SiddhiEventFactory siddhiEventFactory = new SiddhiEventFactory(2); Assert.assertEquals(2, siddhiEventFactory.newInstance().getData().length); StreamEventFactory streamEventFactory = new StreamEventFactory(2, 3, 4); StreamEvent streamEvent = streamEventFactory.newInstance(); Assert.assertEquals(2, streamEvent.getBeforeWindowData().length); Assert.assertEquals(3, streamEvent.getOnAfterWindowData().length); Assert.assertEquals(4, streamEvent.getOutputData().length); } @Test public void testEventPool() { StreamEventPool streamEventPool = new StreamEventPool(2, 3, 1, 4); StreamEvent[] streamEvents = new StreamEvent[5]; for (int i = 0; i < 5; i++) { streamEvents[i] = streamEventPool.borrowEvent(); } Assert.assertEquals(0, streamEventPool.getBufferedEventsSize()); for (int i = 0; i < 5; i++) { streamEventPool.returnEvents(streamEvents[i]); } Assert.assertEquals(4, streamEventPool.getBufferedEventsSize()); streamEventPool.borrowEvent(); Assert.assertEquals(3, streamEventPool.getBufferedEventsSize()); } @Test public void testPassThroughStreamEventConverter() { Attribute symbol = new Attribute("symbol", Attribute.Type.STRING); Attribute price = new Attribute("price", Attribute.Type.DOUBLE); Attribute volume = new Attribute("volume", Attribute.Type.INT); MetaStreamEvent metaStreamEvent = new MetaStreamEvent(); metaStreamEvent.addOutputData(symbol); metaStreamEvent.addOutputData(price); metaStreamEvent.addOutputData(volume); StreamDefinition streamDefinition = StreamDefinition.id("cseEventStream").attribute("symbol", Attribute.Type .STRING).attribute("price", Attribute.Type.DOUBLE).attribute("volume", Attribute.Type.INT); Event event = new Event(System.currentTimeMillis(), new Object[]{"WSO2", 200.0, 50}); metaStreamEvent.addInputDefinition(streamDefinition); StreamEventConverter converter = StreamEventConverterFactory.constructEventConverter(metaStreamEvent); StreamEventPool eventPool = new StreamEventPool(metaStreamEvent, 5); StreamEvent borrowedEvent = eventPool.borrowEvent(); converter.convertEvent(event, borrowedEvent); Assert.assertTrue(converter instanceof ZeroStreamEventConverter); Assert.assertEquals(3, borrowedEvent.getOutputData().length); Assert.assertEquals("WSO2", borrowedEvent.getOutputData()[0]); Assert.assertEquals(200.0, borrowedEvent.getOutputData()[1]); Assert.assertEquals(50, borrowedEvent.getOutputData()[2]); } @Test public void testSimpleStreamEventConverter() { Attribute price = new Attribute("price", Attribute.Type.DOUBLE); Attribute symbol = new Attribute("symbol", Attribute.Type.STRING); MetaStreamEvent metaStreamEvent = new MetaStreamEvent(); metaStreamEvent.addOutputData(symbol); metaStreamEvent.addOutputData(price); StreamDefinition streamDefinition = StreamDefinition.id("cseEventStream").attribute("symbol", Attribute.Type .STRING).attribute("price", Attribute.Type.DOUBLE).attribute("volume", Attribute.Type.INT); Event event = new Event(System.currentTimeMillis(), new Object[]{"WSO2", 200, 50}); metaStreamEvent.addInputDefinition(streamDefinition); StreamEventConverter converter = StreamEventConverterFactory.constructEventConverter(metaStreamEvent); StreamEventPool eventPool = new StreamEventPool(metaStreamEvent, 5); StreamEvent borrowedEvent = eventPool.borrowEvent(); converter.convertEvent(event, borrowedEvent); Assert.assertTrue(converter instanceof SimpleStreamEventConverter); Assert.assertNull(borrowedEvent.getBeforeWindowData()); Assert.assertNull(borrowedEvent.getOnAfterWindowData()); Assert.assertEquals(2, borrowedEvent.getOutputData().length); Assert.assertEquals(200, borrowedEvent.getOutputData()[1]); Assert.assertEquals("WSO2", borrowedEvent.getOutputData()[0]); } @Test public void testStreamEventConverter() { Attribute price = new Attribute("price", Attribute.Type.DOUBLE); Attribute volume = new Attribute("volume", Attribute.Type.INT); Attribute symbol = new Attribute("symbol", Attribute.Type.STRING); MetaStreamEvent metaStreamEvent = new MetaStreamEvent(); metaStreamEvent.addData(volume); metaStreamEvent.initializeAfterWindowData(); metaStreamEvent.addData(price); metaStreamEvent.addOutputData(symbol); metaStreamEvent.addOutputData(null); //complex attribute StreamDefinition streamDefinition = StreamDefinition.id("cseEventStream").attribute("symbol", Attribute.Type .STRING).attribute("price", Attribute.Type.DOUBLE).attribute("volume", Attribute.Type.INT); Event event = new Event(System.currentTimeMillis(), new Object[]{"WSO2", 200, 50}); metaStreamEvent.addInputDefinition(streamDefinition); StreamEventConverter converter = StreamEventConverterFactory.constructEventConverter(metaStreamEvent); StreamEventPool eventPool = new StreamEventPool(metaStreamEvent, 5); StreamEvent borrowedEvent = eventPool.borrowEvent(); converter.convertEvent(event, borrowedEvent); Assert.assertTrue(converter instanceof SelectiveStreamEventConverter); Assert.assertEquals(1, borrowedEvent.getBeforeWindowData().length); //volume Assert.assertEquals(1, borrowedEvent.getOnAfterWindowData().length); //price Assert.assertEquals(2, borrowedEvent.getOutputData().length); //symbol and avgPrice Assert.assertEquals(50, borrowedEvent.getBeforeWindowData()[0]); Assert.assertEquals(200, borrowedEvent.getOnAfterWindowData()[0]); Assert.assertEquals("WSO2", borrowedEvent.getOutputData()[0]); } @Test public void testExpressionExecutors() { // StreamDefinition streamDefinition = StreamDefinition.id("cseEventStream").attribute("symbol", Attribute // .Type.STRING).attribute("price", Attribute.Type.FLOAT).attribute("volume", Attribute.Type.INT); VariableExpressionExecutor priceVariableExpressionExecutor = new VariableExpressionExecutor(new Attribute ("price", Attribute.Type.FLOAT), 0, 0); priceVariableExpressionExecutor.setPosition(new int[]{0, SiddhiConstants.UNKNOWN_STATE, SiddhiConstants .OUTPUT_DATA_INDEX, 1}); ExpressionExecutor addExecutor = new AddExpressionExecutorFloat(new ConstantExpressionExecutor(10f, Attribute .Type.FLOAT), priceVariableExpressionExecutor); StreamEvent event = new StreamEvent(0, 0, 3); event.setOutputData(new Object[]{"WSO2", 10f, 5}); Assert.assertEquals("Result of adding should be 20.0", 20f, addExecutor.execute(event)); } @Test public void testConditionExpressionExecutors() { // StreamDefinition streamDefinition = StreamDefinition.id("cseEventStream").attribute("symbol", Attribute // .Type.STRING).attribute("price", Attribute.Type.FLOAT).attribute("volume", Attribute.Type.INT); VariableExpressionExecutor priceVariableExpressionExecutor = new VariableExpressionExecutor(new Attribute ("price", Attribute.Type.FLOAT), 0, 0); priceVariableExpressionExecutor.setPosition(new int[]{0, SiddhiConstants.UNKNOWN_STATE, SiddhiConstants .OUTPUT_DATA_INDEX, 1}); VariableExpressionExecutor volumeVariableExpressionExecutor = new VariableExpressionExecutor(new Attribute ("volume", Attribute.Type.INT), 0, 0); volumeVariableExpressionExecutor.setPosition(new int[]{0, SiddhiConstants.UNKNOWN_STATE, SiddhiConstants .OUTPUT_DATA_INDEX, 2}); ExpressionExecutor compareLessThanExecutor = new LessThanCompareConditionExpressionExecutorFloatFloat(new ConstantExpressionExecutor(10f, Attribute.Type.FLOAT), priceVariableExpressionExecutor); ExpressionExecutor compareGreaterThanExecutor = new GreaterThanCompareConditionExpressionExecutorIntInt(new ConstantExpressionExecutor(10, Attribute.Type.INT), volumeVariableExpressionExecutor); ExpressionExecutor andExecutor = new AndConditionExpressionExecutor(compareLessThanExecutor, compareGreaterThanExecutor); int count = 0; for (int i = 0; i < 3; i++) { StreamEvent event = new StreamEvent(0, 0, 3); event.setOutputData(new Object[]{"WSO2", i * 11f, 5}); if ((Boolean) andExecutor.execute(event)) { count++; } } Assert.assertEquals("Two events should pass through executor", 2, count); } @Test(expected = OperationNotSupportedException.class) public void testConditionExpressionExecutorValidation() { // StreamDefinition streamDefinition = StreamDefinition.id("cseEventStream").attribute("symbol", Attribute // .Type.STRING).attribute("price", Attribute.Type.FLOAT).attribute("volume", Attribute.Type.INT); VariableExpressionExecutor volumeVariableExpressionExecutor = new VariableExpressionExecutor(new Attribute ("volume", Attribute.Type.INT), 0, 0); volumeVariableExpressionExecutor.setPosition(new int[]{0, SiddhiConstants.UNKNOWN_STATE, SiddhiConstants .OUTPUT_DATA_INDEX, 2}); ConstantExpressionExecutor constantExpressionExecutor = new ConstantExpressionExecutor(10f, Attribute.Type .FLOAT); ExpressionExecutor compareGreaterThanExecutor = new GreaterThanCompareConditionExpressionExecutorIntInt(new ConstantExpressionExecutor(10, Attribute.Type.INT), volumeVariableExpressionExecutor); ExpressionExecutor andExecutor = new AndConditionExpressionExecutor(constantExpressionExecutor, compareGreaterThanExecutor); } @Test public void testQueryParser() { StreamDefinition streamDefinition = StreamDefinition.id("cseEventStream").attribute("symbol", Attribute.Type .STRING).attribute("price", Attribute.Type.FLOAT).attribute("volume", Attribute.Type.INT); StreamDefinition outStreamDefinition = StreamDefinition.id("outputStream").attribute("symbol", Attribute.Type .STRING).attribute("price", Attribute.Type.FLOAT); Query query = new Query(); query.annotation(Annotation.annotation("info").element("name", "query1")); query.from(InputStream.stream("cseEventStream").filter(Expression.compare(Expression.variable("volume"), Compare.Operator.NOT_EQUAL, Expression.value(50)))); query.select(Selector.selector().select("symbol", Expression.variable("symbol")).select("price", Expression .variable("price"))); query.insertInto("outputStream"); Map<String, AbstractDefinition> tableDefinitionMap = new HashMap<String, AbstractDefinition>(); Map<String, AbstractDefinition> windowDefinitionMap = new HashMap<String, AbstractDefinition>(); Map<String, Table> tableMap = new HashMap<String, Table>(); Map<String, Window> eventWindowMap = new HashMap<String, Window>(); Map<String, List<Source>> eventSourceMap = new HashMap<String, List<Source>>(); Map<String, List<Sink>> eventSinkMap = new HashMap<String, List<Sink>>(); Map<String, AbstractDefinition> streamDefinitionMap = new HashMap<String, AbstractDefinition>(); LockSynchronizer lockSynchronizer = new LockSynchronizer(); streamDefinitionMap.put("cseEventStream", streamDefinition); streamDefinitionMap.put("outputStream", outStreamDefinition); SiddhiContext siddhicontext = new SiddhiContext(); ExecutionPlanContext context = new ExecutionPlanContext(); context.setSiddhiContext(siddhicontext); context.setElementIdGenerator(new ElementIdGenerator(context.getName())); context.setSnapshotService(new SnapshotService(context)); QueryRuntime runtime = QueryParser.parse(query, context, streamDefinitionMap, tableDefinitionMap, windowDefinitionMap, tableMap, eventWindowMap, eventSourceMap, eventSinkMap, lockSynchronizer); Assert.assertNotNull(runtime); Assert.assertTrue(runtime.getStreamRuntime() instanceof SingleStreamRuntime); Assert.assertNotNull(runtime.getSelector()); Assert.assertTrue(runtime.getMetaComplexEvent() instanceof MetaStreamEvent); } @Test public void testUpdateMetaEvent() { StreamDefinition streamDefinition = StreamDefinition.id("cseEventStream").attribute("symbol", Attribute.Type .STRING).attribute("price", Attribute.Type.FLOAT).attribute("volume", Attribute.Type.INT); Attribute price = new Attribute("price", Attribute.Type.FLOAT); Attribute volume = new Attribute("volume", Attribute.Type.INT); Attribute symbol = new Attribute("symbol", Attribute.Type.STRING); MetaStreamEvent metaStreamEvent = new MetaStreamEvent(); metaStreamEvent.addData(volume); metaStreamEvent.addData(price); metaStreamEvent.addData(symbol); metaStreamEvent.initializeAfterWindowData(); metaStreamEvent.addData(price); metaStreamEvent.addOutputData(symbol); metaStreamEvent.addOutputData(null); MetaStateEvent metaStateEvent = new MetaStateEvent(1); metaStateEvent.addEvent(metaStreamEvent); VariableExpressionExecutor priceVariableExpressionExecutor = new VariableExpressionExecutor(new Attribute ("price", Attribute.Type.FLOAT), 0, 0); VariableExpressionExecutor volumeVariableExpressionExecutor = new VariableExpressionExecutor(new Attribute ("volume", Attribute.Type.INT), 0, 0); VariableExpressionExecutor symbolVariableExpressionExecutor = new VariableExpressionExecutor(new Attribute ("symbol", Attribute.Type.STRING), 0, 0); QueryParserHelper.reduceMetaComplexEvent(metaStateEvent); QueryParserHelper.updateVariablePosition(metaStateEvent, Arrays.asList(priceVariableExpressionExecutor, volumeVariableExpressionExecutor, symbolVariableExpressionExecutor)); Assert.assertEquals(1, metaStreamEvent.getBeforeWindowData().size()); Assert.assertEquals(1, metaStreamEvent.getOnAfterWindowData().size()); Assert.assertEquals(2, metaStreamEvent.getOutputData().size()); Assert.assertArrayEquals(new int[]{0, 0, 1, 0}, priceVariableExpressionExecutor.getPosition()); Assert.assertArrayEquals(new int[]{0, 0, 0, 0}, volumeVariableExpressionExecutor.getPosition()); Assert.assertArrayEquals(new int[]{0, 0, 2, 0}, symbolVariableExpressionExecutor.getPosition()); } }