Answer to Stackoverflow question asking how to build an event session (with sliding expiration - 30s):

Types:

package com.test;

import java.util.List;

declare EventA
    @role(event)
    // attributes 
    
    eventTime: long;
    deviceId: int;
    numThings: int;
end

declare Group
    eventTime: long @key;
    events: List;
end

declare Summary
    eventTime: long;
    sumNumThings: int;
end

Rules:

package com.test;

import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;

global co.streamx.kie.api.runtime.Events events;
global co.streamx.kie.api.runtime.Console console;

rule "GroupCreate"
when
    // for every new EventA
    $a: EventA($time: eventTime) from entry-point events
    // check there is no group
    not (exists(Group(eventTime == $time)))
then
    insert(new Group($time, new ArrayList()));
    console.log("Got TS: %d", events.getTimestamp($a, "events"));
end

rule "GroupJoin"
when
    // for every new EventA
    $a : EventA() from entry-point events
    // get event's group
    $g: Group(eventTime == $a.eventTime)
then
    $g.getEvents().add($a);
end

rule "Summarize"
// if session timed out, clean up first
salience 5
when
    // for every EventA
    $a : EventA() from entry-point events
    // check there is no more events within 30 seconds
    not (exists(EventA(this != $a, eventTime == $a.eventTime,
        this after[1ms, 30s] $a) from entry-point events))
    // get event's group
    $g: Group(eventTime == $a.eventTime)
then
    int sum = (int)$g.getEvents().stream().collect(Collectors.summingInt(EventA::getNumThings));
    insertLogical(new Summary($g.getEventTime(), sum));
    
    // cleanup
    for (Object $x : $g.getEvents())
        delete($x);
    delete($g);
end