/* *************************************************************************************** * 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.Configuration; import com.espertech.esper.client.EPServiceProvider; import com.espertech.esper.client.EPServiceProviderManager; import com.espertech.esper.client.scopetest.EPAssertionUtil; import com.espertech.esper.client.scopetest.SupportUpdateListener; import com.espertech.esper.client.time.CurrentTimeEvent; import com.espertech.esper.client.time.CurrentTimeSpanEvent; import com.espertech.esper.client.util.DateTime; import com.espertech.esper.metrics.instrumentation.InstrumentationHelper; import com.espertech.esper.supportregression.client.SupportConfigFactory; import junit.framework.TestCase; public class TestSolutionPattern_PortScan extends TestCase { private EPServiceProvider epService; private SupportUpdateListener listener; public void setUp() { Configuration configuration = SupportConfigFactory.getConfiguration(); epService = EPServiceProviderManager.getDefaultProvider(configuration); epService.initialize(); epService.getEPRuntime().sendEvent(new CurrentTimeEvent(0)); setCurrentTime("8:00:00"); if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());} listener = new SupportUpdateListener(); } public void tearDown() { if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();} listener = null; } public void testPortScan_PrimarySuccess() throws Exception { deployPortScan(); sendEventMultiple(20, "A", "B"); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), "type,cnt".split(","), new Object[] {"DETECTED", 20L}); } public void testPortScan_KeepAlerting() throws Exception { deployPortScan(); sendEventMultiple(20, "A", "B"); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), "type,cnt".split(","), new Object[] {"DETECTED", 20L}); setCurrentTime("8:00:29"); sendEventMultiple(20, "A", "B"); setCurrentTime("8:00:59"); sendEventMultiple(20, "A", "B"); assertFalse(listener.isInvoked()); setCurrentTime("8:01:00"); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), "type,cnt".split(","), new Object[] {"UPDATE", 20L}); } public void testPortScan_FallsUnderThreshold() throws Exception { deployPortScan(); sendEventMultiple(20, "A", "B"); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), "type,cnt".split(","), new Object[] {"DETECTED", 20L}); setCurrentTime("8:01:00"); EPAssertionUtil.assertProps(listener.getAndResetLastNewData()[0], "type,cnt".split(","), new Object[] {"DONE", 0L}); } private void sendEventMultiple(int count, String src, String dst) { for (int i = 0; i < count; i++) { sendEvent(src, dst, 16+i, "m" + count); } } private void sendEvent(String src, String dst, int port, String marker) { epService.getEPRuntime().sendEvent(new Object[] {src, dst, port, marker}, "PortScanEvent"); } private void setCurrentTime(String time) { String timestamp = "2002-05-30T" + time + ".000"; long current = DateTime.parseDefaultMSec(timestamp); System.out.println("Advancing time to " + timestamp + " msec " + current); epService.getEPRuntime().sendEvent(new CurrentTimeSpanEvent(current)); } private void deployPortScan() throws Exception { String epl = "create objectarray schema PortScanEvent(src string, dst string, port int, marker string);\n" + "\n" + "create table ScanCountTable(src string primary key, dst string primary key, cnt count(*), win window(*) @type(PortScanEvent));\n" + "\n" + "into table ScanCountTable\n" + "insert into CountStream\n" + "select src, dst, count(*) as cnt, window(*) as win\n" + "from PortScanEvent#unique(src, dst, port)#time(30 sec) group by src,dst;\n" + "\n" + "create window SituationsWindow#keepall (src string, dst string, detectionTime long);\n" + "\n" + "on CountStream(cnt >= 20) as cs\n" + "merge SituationsWindow sw\n" + "where cs.src = sw.src and cs.dst = sw.dst\n" + "when not matched \n" + " then insert select src, dst, current_timestamp as detectionTime\n" + " then insert into OutputAlerts select 'DETECTED' as type, cs.cnt as cnt, cs.win as contributors;\n" + "\n" + "on pattern [every timer:at(*, *, *, *, *)] \n" + "insert into OutputAlerts \n" + "select 'UPDATE' as type, ScanCountTable[src, dst].cnt as cnt, ScanCountTable[src, dst].win as contributors\n" + "from SituationsWindow sc;\n" + "\n" + "on pattern [every timer:at(*, *, *, *, *)] \n" + "merge SituationsWindow sw\n" + "when matched and (select cnt from ScanCountTable where src = sw.src and dst = sw.dst) < 10\n" + " then delete\n" + " then insert into OutputAlerts select 'DONE' as type, ScanCountTable[src, dst].cnt as cnt, null as contributors \n" + "when matched and detectionTime.after(current_timestamp, 16 hours)\n" + " then delete\n" + " then insert into OutputAlerts select 'EXPIRED' as type, -1L as cnt, null as contributors;\n" + "\n" + // For more output: "@audit() select * from CountStream;\n" + "@name('output') select * from OutputAlerts;\n"; epService.getEPAdministrator().getDeploymentAdmin().parseDeploy(epl); epService.getEPAdministrator().getStatement("output").addListener(listener); System.out.println(epl); } }