package sushi.transformation.test;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import sushi.esper.SushiStreamProcessingAdapter;
import sushi.event.SushiEvent;
import sushi.event.SushiEventType;
import sushi.event.attribute.SushiAttribute;
import sushi.event.attribute.SushiAttributeTypeEnum;
import sushi.eventhandling.Broker;
import sushi.excel.importer.ExcelImporter;
import sushi.persistence.Persistor;
import sushi.transformation.TransformationManager;
import sushi.transformation.TransformationListener;
import sushi.transformation.TransformationRule;
import sushi.transformation.EsperTransformationRuleParser;
import sushi.transformation.collection.SushiPatternTree;
import sushi.transformation.element.EventTypeElement;
import sushi.transformation.element.FilterExpressionElement;
import sushi.transformation.element.FilterExpressionOperatorEnum;
import sushi.transformation.element.PatternOperatorElement;
import sushi.transformation.element.PatternOperatorEnum;
import sushi.transformation.element.externalknowledge.ExternalKnowledgeExpressionSet;
public class TransformationRuleFromPatternTreeTest {
private ExcelImporter excelNormalizer;
private String folder = System.getProperty("user.dir") + "/src/main/resources/truckUsageWithExternalKnowledgeTest/";
private String firstObuEventsFile = folder + "OBU_Events_01.xls";
private String secondObuEventsFile = folder + "OBU_Events_02.xls";
private String firstTruckUsageFile = folder + "Truck_Usage_Plan_Advanced_01.xls";
private String secondTruckUsageFile = folder + "Truck_Usage_Plan_Advanced_02.xls";
@Before
public void setup() {
Persistor.useTestEnviroment();
SushiStreamProcessingAdapter.clearInstance();
excelNormalizer = new ExcelImporter();
}
@Test
public void testTruckUsageFiles() {
List<SushiAttribute> attributes;
SushiAttribute rootAttribute5 = new SushiAttribute("Driver", SushiAttributeTypeEnum.STRING);
SushiAttribute rootAttribute6 = new SushiAttribute("Truck", SushiAttributeTypeEnum.STRING);
SushiAttribute rootAttribute7 = new SushiAttribute("Action", SushiAttributeTypeEnum.STRING);
attributes = Arrays.asList(rootAttribute5, rootAttribute6, rootAttribute7);
SushiEventType eventType1 = new SushiEventType("truckUsage", attributes, "Timestamp");
assertTrue("Event type already registered", !SushiStreamProcessingAdapter.getInstance().isEventType(eventType1));
Broker.send(eventType1);
SushiAttribute rootAttribute8 = new SushiAttribute("Driver", SushiAttributeTypeEnum.STRING);
SushiAttribute rootAttribute9 = new SushiAttribute("Location", SushiAttributeTypeEnum.STRING);
attributes = Arrays.asList(rootAttribute8, rootAttribute9);
SushiEventType eventType2 = new SushiEventType("obuEvent", attributes, "Timestamp");
Broker.send(eventType2);
SushiAttribute rootAttribute10 = new SushiAttribute("Truck Usage Start", SushiAttributeTypeEnum.DATE);
SushiAttribute rootAttribute11 = new SushiAttribute("Truck", SushiAttributeTypeEnum.STRING);
SushiAttribute rootAttribute12 = new SushiAttribute("Driver", SushiAttributeTypeEnum.STRING);
SushiAttribute rootAttribute13 = new SushiAttribute("Location", SushiAttributeTypeEnum.STRING);
attributes = Arrays.asList(rootAttribute10, rootAttribute11, rootAttribute12, rootAttribute13);
SushiEventType eventType3 = new SushiEventType("enrichedObuEvent", attributes, "Timestamp");
Broker.send(eventType3);
assertTrue("Number of event types should be 3 but was " + SushiStreamProcessingAdapter.getInstance().getWindowNames().length, SushiStreamProcessingAdapter.getInstance().getWindowNames().length == 3);
SushiPatternTree patternTree = new SushiPatternTree();
EventTypeElement eventTypeElementA = new EventTypeElement(getNextID(patternTree), eventType1);
eventTypeElementA.setAlias("A");
patternTree.addElement(eventTypeElementA);
FilterExpressionElement filterExpressionElementA1 = new FilterExpressionElement(getNextID(patternTree), FilterExpressionOperatorEnum.EQUALS);
filterExpressionElementA1.setParent(eventTypeElementA);
filterExpressionElementA1.setLeftHandSideExpression("A.Action");
filterExpressionElementA1.setRightHandSideExpression("'Start'");
patternTree.addElement(filterExpressionElementA1);
EventTypeElement eventTypeElementB = new EventTypeElement(getNextID(patternTree), eventType2);
eventTypeElementB.setAlias("B");
patternTree.addElement(eventTypeElementB);
FilterExpressionElement filterExpressionElementB1 = new FilterExpressionElement(getNextID(patternTree), FilterExpressionOperatorEnum.EQUALS);
filterExpressionElementB1.setParent(eventTypeElementB);
filterExpressionElementB1.setLeftHandSideExpression("A.Driver");
filterExpressionElementB1.setRightHandSideExpression("B.Driver");
patternTree.addElement(filterExpressionElementB1);
FilterExpressionElement filterExpressionElementB2 = new FilterExpressionElement(getNextID(patternTree), FilterExpressionOperatorEnum.SMALLER_THAN);
filterExpressionElementB2.setParent(eventTypeElementB);
filterExpressionElementB2.setLeftHandSideExpression("A.Timestamp.getTime()");
filterExpressionElementB2.setRightHandSideExpression("B.Timestamp.getTime()");
patternTree.addElement(filterExpressionElementB2);
EventTypeElement eventTypeElementC = new EventTypeElement(getNextID(patternTree), eventType1);
eventTypeElementC.setAlias("C");
patternTree.addElement(eventTypeElementC);
FilterExpressionElement filterExpressionElementC1 = new FilterExpressionElement(getNextID(patternTree), FilterExpressionOperatorEnum.EQUALS);
filterExpressionElementC1.setParent(eventTypeElementC);
filterExpressionElementC1.setLeftHandSideExpression("C.Action");
filterExpressionElementC1.setRightHandSideExpression("'End'");
patternTree.addElement(filterExpressionElementC1);
FilterExpressionElement filterExpressionElementC2 = new FilterExpressionElement(getNextID(patternTree), FilterExpressionOperatorEnum.SMALLER_THAN);
filterExpressionElementC2.setParent(eventTypeElementC);
filterExpressionElementC2.setLeftHandSideExpression("A.Timestamp.getTime()");
filterExpressionElementC2.setRightHandSideExpression("C.Timestamp.getTime()");
patternTree.addElement(filterExpressionElementC2);
FilterExpressionElement filterExpressionElementC3 = new FilterExpressionElement(getNextID(patternTree), FilterExpressionOperatorEnum.EQUALS);
filterExpressionElementC3.setParent(eventTypeElementC);
filterExpressionElementC3.setLeftHandSideExpression("A.Driver");
filterExpressionElementC3.setRightHandSideExpression("C.Driver");
patternTree.addElement(filterExpressionElementC3);
FilterExpressionElement filterExpressionElementC4 = new FilterExpressionElement(getNextID(patternTree), FilterExpressionOperatorEnum.EQUALS);
filterExpressionElementC4.setParent(eventTypeElementC);
filterExpressionElementC4.setLeftHandSideExpression("A.Truck");
filterExpressionElementC4.setRightHandSideExpression("C.Truck");
patternTree.addElement(filterExpressionElementC4);
PatternOperatorElement patternOperatorElement1 = new PatternOperatorElement(getNextID(patternTree), PatternOperatorEnum.NOT);
eventTypeElementC.setParent(patternOperatorElement1);
patternTree.addElement(patternOperatorElement1);
PatternOperatorElement patternOperatorElement2 = new PatternOperatorElement(getNextID(patternTree), PatternOperatorEnum.AND);
eventTypeElementB.setParent(patternOperatorElement2);
patternOperatorElement1.setParent(patternOperatorElement2);
patternTree.addElement(patternOperatorElement2);
PatternOperatorElement patternOperatorElement3 = new PatternOperatorElement(getNextID(patternTree), PatternOperatorEnum.EVERY);
patternOperatorElement2.setParent(patternOperatorElement3);
patternTree.addElement(patternOperatorElement3);
PatternOperatorElement patternOperatorElement4 = new PatternOperatorElement(getNextID(patternTree), PatternOperatorEnum.EVERY);
eventTypeElementA.setParent(patternOperatorElement4);
patternTree.addElement(patternOperatorElement4);
PatternOperatorElement patternOperatorElement5 = new PatternOperatorElement(getNextID(patternTree), PatternOperatorEnum.FOLLOWED_BY);
patternOperatorElement4.setParent(patternOperatorElement5);
patternOperatorElement3.setParent(patternOperatorElement5);
patternTree.addElement(patternOperatorElement5);
PatternOperatorElement patternOperatorElement6 = new PatternOperatorElement(getNextID(patternTree), PatternOperatorEnum.EVERY);
patternOperatorElement5.setParent(patternOperatorElement6);
patternTree.addElement(patternOperatorElement6);
Map<String, String> attributeIdentifiersAndExpressions = new HashMap<String, String>();
attributeIdentifiersAndExpressions.put("Timestamp", "B.Timestamp");
attributeIdentifiersAndExpressions.put("Driver", "A.Driver");
attributeIdentifiersAndExpressions.put("Truck", "A.Truck");
attributeIdentifiersAndExpressions.put("Location", "B.Location");
attributeIdentifiersAndExpressions.put("Truck_Usage_Start", "A.Timestamp");
String query = EsperTransformationRuleParser.getInstance().parseRule(patternTree, attributeIdentifiersAndExpressions, null);
assertTrue("Query was not build correctly.", query.equals("" +
"SELECT (A.Driver) AS Driver, (A.Timestamp) AS Truck_Usage_Start, " +
"(A.Truck) AS Truck, (B.Location) AS Location, (B.Timestamp) AS Timestamp " +
"FROM Pattern [(EVERY " +
"((EVERY (A=truckUsage(((A.Action) = ('Start'))))) " +
"-> " +
"(EVERY ((B=obuEvent(((A.Driver) = (B.Driver)), ((A.Timestamp.getTime()) < (B.Timestamp.getTime())))) " +
"AND (NOT (C=truckUsage(((C.Action) = ('End')), ((A.Timestamp.getTime()) < (C.Timestamp.getTime())), " +
"((A.Driver) = (C.Driver)), ((A.Truck) = (C.Truck)))))))))]"));
TransformationRule firstRule = new TransformationRule(eventType3, "someRuleName", patternTree, attributeIdentifiersAndExpressions, new HashMap<String, ExternalKnowledgeExpressionSet>());
TransformationListener firstListener = TransformationManager.getInstance().register(firstRule.save());
loadData(eventType1, firstTruckUsageFile);
assertTrue("Number of generated enrichedObuEvent events in the event processing engine should be 0, but was " + firstListener.getNumberOfEventsFired(), firstListener.getNumberOfEventsFired() == 0);
assertTrue("Number of generated enrichedObuEvent events in the database should be 0, but was " + SushiEvent.findByEventType(eventType3).size(), SushiEvent.findByEventType(eventType3).size() == 0);
loadData(eventType2, firstObuEventsFile);
assertTrue("Number of generated enrichedObuEvent events in the event processing engine should be 16, but was " + firstListener.getNumberOfEventsFired(), firstListener.getNumberOfEventsFired() == 16);
assertTrue("Number of generated enrichedObuEvent events in the database should be 16, but was " + SushiEvent.findByEventType(eventType3).size(), SushiEvent.findByEventType(eventType3).size() == 16);
loadData(eventType1, secondTruckUsageFile);
assertTrue("Number of generated enrichedObuEvent events in the event processing engine should be 16, but was " + firstListener.getNumberOfEventsFired(), firstListener.getNumberOfEventsFired() == 16);
assertTrue("Number of generated enrichedObuEvent events in the database should be 16, but was " + SushiEvent.findByEventType(eventType3).size(), SushiEvent.findByEventType(eventType3).size() == 16);
firstRule.remove();
TransformationManager.getInstance().removeFromEsper(firstRule);
loadData(eventType2, secondObuEventsFile);
assertTrue("Number of generated enrichedObuEvent events in the database should be 16, but was " + SushiEvent.findByEventType(eventType3).size(), SushiEvent.findByEventType(eventType3).size() == 16);
}
public void loadData(SushiEventType eventType, String filePath) {
List<SushiAttribute> attributes = eventType.getValueTypes();
String timestamp = eventType.getTimestampName();
// insert events into event type via SushiEsper
List<SushiEvent> events = excelNormalizer.importEventsFromFile(filePath, attributes, timestamp);
for (SushiEvent event : events) {
event.setEventType(eventType);
}
Broker.send(events);
}
public int getNextID(SushiPatternTree patternTree) {
return patternTree.getElements().size() + 1;
}
}