package sushi.transformation.test; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.Date; import java.util.List; 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.query.SushiQuery; import sushi.query.SushiQueryTypeEnum; import sushi.transformation.TransformationManager; import sushi.transformation.TransformationListener; import sushi.transformation.TransformationRule; public class TruckUsageWithExternalKnowledgeTest { private ExcelImporter excelNormalizer; private String folder = System.getProperty("user.dir") + "/src/main/resources/truckUsageWithExternalKnowledgeTest/"; private String truckRouteFile = folder + "Distances.xls"; 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 rootAttribute1 = new SushiAttribute("Origin", SushiAttributeTypeEnum.STRING); SushiAttribute rootAttribute2 = new SushiAttribute("Destination", SushiAttributeTypeEnum.STRING); SushiAttribute rootAttribute3 = new SushiAttribute("Distance in km", SushiAttributeTypeEnum.INTEGER); SushiAttribute rootAttribute4 = new SushiAttribute("Time approx", SushiAttributeTypeEnum.INTEGER); attributes = Arrays.asList(rootAttribute1, rootAttribute2, rootAttribute3, rootAttribute4); SushiEventType eventType1 = new SushiEventType("TruckRoute", attributes, "Import time"); Broker.send(eventType1); 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 eventType2 = new SushiEventType("truckUsage", attributes, "Timestamp"); assertTrue("Event type already registered", !SushiStreamProcessingAdapter.getInstance().isEventType(eventType2)); Broker.send(eventType2); SushiAttribute rootAttribute8 = new SushiAttribute("Driver", SushiAttributeTypeEnum.STRING); SushiAttribute rootAttribute9 = new SushiAttribute("Location", SushiAttributeTypeEnum.STRING); attributes = Arrays.asList(rootAttribute8, rootAttribute9); SushiEventType eventType3 = new SushiEventType("obuEvent", attributes, "Timestamp"); Broker.send(eventType3); 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 eventType4 = new SushiEventType("enrichedObuEvent", attributes, "Timestamp"); Broker.send(eventType4); SushiAttribute rootAttribute14 = new SushiAttribute("Timestamp Second Location", SushiAttributeTypeEnum.DATE); SushiAttribute rootAttribute15 = new SushiAttribute("Origin", SushiAttributeTypeEnum.STRING); SushiAttribute rootAttribute16 = new SushiAttribute("Destination", SushiAttributeTypeEnum.STRING); SushiAttribute rootAttribute17 = new SushiAttribute("Truck Usage Start", SushiAttributeTypeEnum.DATE); SushiAttribute rootAttribute18 = new SushiAttribute("Truck Usage End", SushiAttributeTypeEnum.DATE); SushiAttribute rootAttribute19 = new SushiAttribute("Driver", SushiAttributeTypeEnum.STRING); SushiAttribute rootAttribute20 = new SushiAttribute("Truck", SushiAttributeTypeEnum.STRING); SushiAttribute rootAttribute21 = new SushiAttribute("Distance in km", SushiAttributeTypeEnum.INTEGER); attributes = Arrays.asList(rootAttribute14, rootAttribute15, rootAttribute16, rootAttribute17, rootAttribute18, rootAttribute19, rootAttribute20, rootAttribute21); SushiEventType eventType5 = new SushiEventType("DrivenRoute", attributes, "Timestamp First Location"); Broker.send(eventType5); SushiAttribute rootAttribute22 = new SushiAttribute("Truck Usage Start", SushiAttributeTypeEnum.DATE); SushiAttribute rootAttribute23 = new SushiAttribute("Truck Usage End", SushiAttributeTypeEnum.DATE); SushiAttribute rootAttribute24 = new SushiAttribute("Truck", SushiAttributeTypeEnum.STRING); SushiAttribute rootAttribute25 = new SushiAttribute("Driver", SushiAttributeTypeEnum.STRING); SushiAttribute rootAttribute26 = new SushiAttribute("Total distance in km", SushiAttributeTypeEnum.INTEGER); attributes = Arrays.asList(rootAttribute22, rootAttribute23, rootAttribute24, rootAttribute25, rootAttribute26); SushiEventType eventType6 = new SushiEventType("TraveledDistance", attributes, "Time of Detection"); Broker.send(eventType6); assertTrue(SushiStreamProcessingAdapter.getInstance().getEventTypeInfo(eventType4, "Driver") == String.class); assertTrue(SushiStreamProcessingAdapter.getInstance().getEventTypeInfo(eventType6, "Timestamp") == Date.class); loadData(eventType1, truckRouteFile); TransformationRule firstRule = new TransformationRule(eventType4, "someRuleName", "SELECT B.Timestamp as Timestamp, B.Driver as Driver, " + "B.Location as Location, A.Truck as Truck, " + "A.Timestamp as Truck_Usage_Start " + "FROM Pattern[every (" + "every A=truckUsage(A.Action='Start') " + "-> " + "every (B=obuEvent(A.Driver = B.Driver AND A.Timestamp.getTime() < B.Timestamp.getTime()) " + "AND NOT C=truckUsage(C.Action='End' AND A.Timestamp.getTime() < C.Timestamp.getTime() " + "AND A.Driver = C.Driver AND A.Truck = C.Truck))" + ")]" ); TransformationListener firstListener = TransformationManager.getInstance().register(firstRule); TransformationRule secondRule = new TransformationRule(eventType5, "someRuleName", "SELECT A.Timestamp AS Timestamp, B.Timestamp AS Timestamp_Second_Location, " + "A.Location AS Origin, B.Location AS Destination, " + "B.Truck_Usage_Start AS Truck_Usage_Start, B.Driver AS Driver, B.Truck AS Truck, " + "coalesce(" + "integerValueFromEvent('TruckRoute', 'Distance_in_km', {'Origin', A.Location, 'Destination', B.Location}), " + "integerValueFromEvent('TruckRoute', 'Distance_in_km', {'Origin', B.Location, 'Destination', A.Location}), " + "0) AS Distance_in_km " + "FROM Pattern[" + "every A=enrichedObuEvent " + "-> " + "(B=enrichedObuEvent(A.Driver = B.Driver AND A.Truck = B.Truck AND A.Truck_Usage_Start.getTime() = B.Truck_Usage_Start.getTime()) " + "AND NOT enrichedObuEvent(Truck_Usage_Start.getTime() = B.Truck_Usage_Start.getTime())" + ")]" ); TransformationListener secondListener = TransformationManager.getInstance().register(secondRule); TransformationRule thirdRule = new TransformationRule(eventType6, "someRuleName", "SELECT currentDate() AS Timestamp, A.Timestamp AS Truck_Usage_Start, C.Timestamp AS Truck_Usage_End, " + "A.Truck AS Truck, A.Driver AS Driver, sumFromEventList(B, 'Distance_in_km') AS Total_distance_in_km " + "FROM Pattern[" + "every A=truckUsage(A.Action='Start') " + "-> " + "(B=DrivenRoute(A.Timestamp.getTime() = B.Truck_Usage_Start.getTime() AND A.Truck = B.Truck) " + "UNTIL (C=truckUsage(C.Action='End' AND A.Timestamp.getTime() < C.Timestamp.getTime() " + "AND A.Driver = C.Driver AND A.Truck = C.Truck))" + ")]" ); TransformationListener thirdListener = TransformationManager.getInstance().register(thirdRule); loadData(eventType2, 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(eventType4).size(), SushiEvent.findByEventType(eventType4).size() == 0); assertTrue("Number of generated DrivenRoute events in the event processing engine should be 0, but was " + secondListener.getNumberOfEventsFired(), secondListener.getNumberOfEventsFired() == 0); assertTrue("Number of generated DrivenRoute events in the database should be 0, but was " + SushiEvent.findByEventType(eventType5).size(), SushiEvent.findByEventType(eventType5).size() == 0); assertTrue("Number of generated TraveledDistance events in the event processing engine should be 0, but was " + thirdListener.getNumberOfEventsFired(), thirdListener.getNumberOfEventsFired() == 0); assertTrue("Number of generated TraveledDistance events in the database should be 0, but was " + SushiEvent.findByEventType(eventType6).size(), SushiEvent.findByEventType(eventType6).size() == 0); loadData(eventType3, 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(eventType4).size(), SushiEvent.findByEventType(eventType4).size() == 16); assertTrue("Number of generated DrivenRoute events in the event processing engine should be 14, but was " + secondListener.getNumberOfEventsFired(), secondListener.getNumberOfEventsFired() == 14); assertTrue("Number of generated DrivenRoute events in the database should be 14, but was " + SushiEvent.findByEventType(eventType5).size(), SushiEvent.findByEventType(eventType5).size() == 14); assertTrue("Number of generated TraveledDistance events in the event processing engine should be 0, but was " + thirdListener.getNumberOfEventsFired(), thirdListener.getNumberOfEventsFired() == 0); assertTrue("Number of generated TraveledDistance events in the database should be 0, but was " + SushiEvent.findByEventType(eventType6).size(), SushiEvent.findByEventType(eventType6).size() == 0); loadData(eventType2, 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(eventType4).size(), SushiEvent.findByEventType(eventType4).size() == 16); assertTrue("Number of generated DrivenRoute events in the event processing engine should be 14, but was " + secondListener.getNumberOfEventsFired(), secondListener.getNumberOfEventsFired() == 14); assertTrue("Number of generated DrivenRoute events in the database should be 14, but was " + SushiEvent.findByEventType(eventType5).size(), SushiEvent.findByEventType(eventType5).size() == 14); assertTrue("Number of generated TraveledDistance events in the event processing engine should be 2, but was " + thirdListener.getNumberOfEventsFired(), thirdListener.getNumberOfEventsFired() == 2); assertTrue("Number of generated TraveledDistance events in the database should be 2, but was " + SushiEvent.findByEventType(eventType6).size(), SushiEvent.findByEventType(eventType6).size() == 2); List<SushiEvent> traveledDistanceEvents = SushiEvent.findByEventType(eventType6); for (SushiEvent event : traveledDistanceEvents) { if (event.getValues().get("Driver").equals("Helmut")) { assertTrue("Distanced traveled by Helmut should be 4886, but was " + event.getValues().get("Total_distance_in_km"), ((Integer) event.getValues().get("Total_distance_in_km")).equals(new Integer(4886))); } else if (event.getValues().get("Driver").equals("Paul")) { assertTrue("Distanced traveled by Paul should be 9196, but was " + event.getValues().get("Total_distance_in_km"), ((Integer) event.getValues().get("Total_distance_in_km")).equals(new Integer(9196))); } } loadData(eventType3, secondObuEventsFile); assertTrue("Number of generated enrichedObuEvent events in the event processing engine should be 27, but was " + firstListener.getNumberOfEventsFired(), firstListener.getNumberOfEventsFired() == 27); assertTrue("Number of generated enrichedObuEvent events in the database should be 27, but was " + SushiEvent.findByEventType(eventType4).size(), SushiEvent.findByEventType(eventType4).size() == 27); assertTrue("Number of generated DrivenRoute events in the event processing engine should be 24, but was " + secondListener.getNumberOfEventsFired(), secondListener.getNumberOfEventsFired() == 24); assertTrue("Number of generated DrivenRoute events in the database should be 24, but was " + SushiEvent.findByEventType(eventType5).size(), SushiEvent.findByEventType(eventType5).size() == 24); assertTrue("Number of generated TraveledDistance events in the event processing engine should be 2, but was " + thirdListener.getNumberOfEventsFired(), thirdListener.getNumberOfEventsFired() == 2); assertTrue("Number of generated TraveledDistance events in the database should be 2, but was " + SushiEvent.findByEventType(eventType6).size(), SushiEvent.findByEventType(eventType6).size() == 2); } 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); } }