/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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.drools.compiler.integrationtests;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.kie.api.time.SessionPseudoClock;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.kie.api.KieBase;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Message;
import org.kie.api.builder.Message.Level;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.KieSessionConfiguration;
import org.kie.api.runtime.conf.ClockTypeOption;
import org.kie.api.runtime.rule.EntryPoint;
import org.kie.internal.KnowledgeBaseFactory;
import static org.junit.Assert.assertEquals;
public class WindowTest {
private KieSession ksession;
private SessionPseudoClock clock;
private String drl =
"package org.drools.compiler.integrationtests;\n" +
"\n" +
"import org.drools.compiler.integrationtests.WindowTest.TestEvent\n" +
"\n" +
"global java.util.List result\n" +
"\n" +
"declare TestEvent\n" +
" @role( event )\n" +
"end\n" +
"\n" +
"declare window DeclaredTimeWindow\n" +
" TestEvent ( name == \"timeDec\" ) over window:time( 50ms ) from entry-point EventStream\n" +
"end\n" +
"\n" +
"declare window DeclaredLengthWindow\n" +
" TestEvent ( name == \"lengthDec\" ) over window:length( 5 ) from entry-point EventStream\n" +
"end\n" +
"\n" +
"query \"TestTimeWindow\"\n" +
" Number( $eventCount : longValue ) from\n" +
" accumulate (\n" +
" $event : TestEvent ( name == \"time\" ) over window:time( 300ms ) from entry-point EventStream,\n" +
" count($event)\n" +
" )\n" +
"end\n" +
"\n" +
"query \"TestLengthWindow\"\n" +
" Number( $eventCount : longValue ) from\n" +
" accumulate (\n" +
" $event : TestEvent ( name == \"length\" ) over window:length( 10 ) from entry-point EventStream,\n" +
" count($event)\n" +
" )\n" +
"end\n" +
"\n" +
"query \"TestDeclaredTimeWindow\"\n" +
" Number( $eventCount : longValue ) from\n" +
" accumulate ( \n" +
" $event : TestEvent () from window DeclaredTimeWindow,\n" +
" count( $event )\n" +
" )\n" +
"end\n" +
"\n" +
"query \"TestDeclaredLengthWindow\"\n" +
" Number( $eventCount : longValue ) from\n" +
" accumulate ( \n" +
" $event : TestEvent () from window DeclaredLengthWindow,\n" +
" count( $event )\n" +
" )\n" +
"end\n" +
"\n" +
"rule \"TestDeclaredTimeWindowRule\"\n" +
" when\n" +
" Number( $eventCount : longValue, longValue > 0 ) from \n" +
" accumulate ( \n" +
" $event : TestEvent () from window DeclaredTimeWindow,\n" +
" count( $event )\n" +
" )\n" +
" then\n" +
" result.add($eventCount);\n" +
"end\n" +
"\n" +
"rule \"TestDeclaredLengthWindowRule\"\n" +
" when\n" +
" Number( $eventCount : longValue, longValue > 0 ) from \n" +
" accumulate ( \n" +
" $event : TestEvent () from window DeclaredLengthWindow,\n" +
" count( $event )\n" +
" )\n" +
" then\n" +
" result.add($eventCount);\n" +
"end\n";
@Before
public void initialization() {
KieFileSystem kfs = KieServices.Factory.get().newKieFileSystem();
kfs.write("src/main/resources/kbase1/window_test.drl", drl);
KieBuilder kbuilder = KieServices.Factory.get().newKieBuilder(kfs);
kbuilder.buildAll();
List<Message> res = kbuilder.getResults().getMessages(Level.ERROR);
assertEquals(res.toString(), 0, res.size());
KieBaseConfiguration kbconf = KnowledgeBaseFactory
.newKnowledgeBaseConfiguration();
kbconf.setOption(EventProcessingOption.STREAM);
KieBase kbase = KieServices.Factory.get()
.newKieContainer(kbuilder.getKieModule().getReleaseId())
.newKieBase(kbconf);
KieSessionConfiguration ksconfig = KnowledgeBaseFactory
.newKnowledgeSessionConfiguration();
ksconfig.setOption(ClockTypeOption.get("pseudo"));
ksession = kbase.newKieSession(ksconfig, null);
clock = ksession.getSessionClock();
}
@After
public void clean() {
ksession.dispose();
}
@Test
public void testTimeWindow() throws InterruptedException {
EntryPoint entryPoint = ksession.getEntryPoint("EventStream");
final long results[] = new long[] { 1, 2, 3, 3, 3 };
TestEvent event;
for (int i = 0; i < 5; i++) {
event = new TestEvent(null, "time", null);
entryPoint.insert(event);
assertEquals(results[i], ksession.getQueryResults("TestTimeWindow")
.iterator().next().get("$eventCount"));
clock.advanceTime(100, TimeUnit.MILLISECONDS);
}
}
@Test
public void testLengthWindow() {
EntryPoint entryPoint = ksession.getEntryPoint("EventStream");
TestEvent event;
for (int i = 1; i <= 20; i++) {
event = new TestEvent(null, "length", null);
entryPoint.insert(event);
assertEquals((i < 10 ? i : 10),
((Long) ksession.getQueryResults("TestLengthWindow")
.iterator().next().get("$eventCount")).intValue());
}
}
@Test
public void testDeclaredTimeWindowInQuery() throws InterruptedException {
final long results[] = new long[] { 1, 2, 3, 4, 5, 5, 5, 5, 5, 5 };
EntryPoint entryPoint = ksession.getEntryPoint("EventStream");
TestEvent event;
for (int i = 0; i < 10; i++) {
event = new TestEvent(null, "timeDec", null);
entryPoint.insert(event);
assertEquals(results[i],
ksession.getQueryResults("TestDeclaredTimeWindow")
.iterator().next().get("$eventCount"));
clock.advanceTime(10, TimeUnit.MILLISECONDS);
}
}
@Test
public void testDeclaredLengthWindowInQuery() {
EntryPoint entryPoint = ksession.getEntryPoint("EventStream");
TestEvent event;
for (int i = 1; i <= 10; i++) {
event = new TestEvent(null, "lengthDec", null);
entryPoint.insert(event);
assertEquals((i < 5 ? i : 5),
((Long) ksession
.getQueryResults("TestDeclaredLengthWindow")
.iterator().next().get("$eventCount")).intValue());
}
}
@Test
public void testDeclaredTimeWindowInRule() throws InterruptedException {
final long results[] = new long[] { 1, 2, 3, 4, 5, 5, 5, 5, 5, 5 };
EntryPoint entryPoint = ksession.getEntryPoint("EventStream");
List<Long> result = new ArrayList<Long>();
ksession.setGlobal("result", result);
TestEvent event;
for (int i = 0; i < 10; i++) {
event = new TestEvent(null, "timeDec", null);
entryPoint.insert(event);
ksession.fireAllRules();
assertEquals(results[i], result.get(result.size() - 1).longValue());
clock.advanceTime(10, TimeUnit.MILLISECONDS);
}
}
@Test
public void testDeclaredLengthWindowInRule() {
EntryPoint entryPoint = ksession.getEntryPoint("EventStream");
List<Long> result = new ArrayList<Long>();
ksession.setGlobal("result", result);
TestEvent event;
for (int i = 1; i <= 10; i++) {
event = new TestEvent(null, "lengthDec", null);
entryPoint.insert(event);
ksession.fireAllRules();
assertEquals((i < 5 ? i : 5), result.get(result.size() - 1)
.longValue());
}
}
public class TestEvent implements Serializable {
private static final long serialVersionUID = -6985691286327371275L;
private final Integer id;
private final String name;
private Serializable value;
public TestEvent(Integer id, String name, Serializable value) {
this.id = id;
this.name = name;
this.value = value;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public Serializable getValue() {
return value;
}
public void setValue(Serializable value) {
this.value = value;
}
@Override
public String toString() {
return String.format("TestEvent[id=%s, name=%s, value=%s]", id,
name, value);
}
}
}