2013-02-11 11 views
5

Drools documentation erwähnt, dass Regeln Attribute wie date-effective und date-expires verwenden können, um einen absoluten Regelgültigkeitszeitraum anzugeben.Drools: Zeitbeschränkte Regel

Zum Beispiel

rule "Date-restricted rule" 
    date-effective "20.2.2013 8:00"  # 8 AM 
    date-expires "20.2.2013 16:00"  # 4 PM 
    when 
    then 
end 

geifert auch periodisch wiederholt Regeln mit Intervall als timer(int:) und cron als timer(cron:) unterstützt, aber es bedeutet, dass die Regel in solchen Punkten abgefeuert wird.

Frage:

Ich bin interessiert, ob es eine Möglichkeit ist, wie in regelmäßigen Abständen zur Verfügung zu spezifizieren (nicht gebrannt) Regeln mit Zeitbeschränkung. Lassen Sie uns zum Beispiel die Geschäftszeiten in einer Firma darstellen - die Operation kann nur während der offiziellen Arbeitszeit, aber nicht außerhalb der Arbeitszeit durchgeführt werden.

würde ich so etwas wie dieses mögen, aber es ist Drools nicht gültige Regel

rule "Time-restricted rule" 
    time-effective "8:00"  # 8 AM 
    time-expires "16:00"  # 4 PM 
    when 
    then 
end 

Wäre möglich sein, diese Regel zu verlängern aktiv 04.00 nur von Montag bis Freitag 8.00 Uhr sein?


Solution (von Esteban Aliverti):

geifert keine direkte Unterstützung für zeitbasierte Keywords haben, aber sie bieten viel mächtiger Kalendermechanismus Quartz Bibliothek. StatefulSession oder WorkingMemory erstellt von StatelessSession verfügt über Methoden zum Definieren dieser Kalender, die Datum und Uhrzeit einschränken können, wann die Regel ausgelöst werden kann.

Beispiel: Regeldefinition

rule "Business hours only" 
    calendars "business-hours" 
    when 
     SomeAttachedClass() 
    then 
     System.out.println("Rule is fired"); 
end 

Kalender Definition

import org.quartz.impl.calendar.DailyCalendar; 

// stateless session and working memory or directly stateful session 
StatefulKnowledgeSession memory = session.newWorkingMemory(); 
// interested time range is 8-16, also there is many Calendar implementation, not just Daily 
DailyCalendar businessHours = new DailyCalendar(8, 0, 0, 0, 16, 0, 0, 0); 
// by default, defined time is EXCLUDED, the inversion makes it INCLUDED and excludes the rest 
businessHours.setInvertTimeRange(true); 
//convert the calendar into a org.drools.time.Calendar 
org.drools.time.Calendar businessHoursCalendar = QuartzHelper.quartzCalendarAdapter(businessHours); 
//Register the calendar in the session with a name. You must use this name in your rules. 
memory.getCalendars().set("business-hours", businessHoursCalendar); 

Antwort

6

Ein besserer Ansatz ist calendar statt timer(cron:) zu verwenden. Ich schaffte es etwas Ähnliches zu tun, was Sie für die folgenden Schritte suchen:

Beim Erstellen der Sitzung, die Sie zum Erstellen und einen Quarz-Kalender zu konfigurieren:

//in this case I'm using a DailyCalendar but you can use whatever implementation of Calendar you want 
org.quartz.impl.calendar.DailyCalendar businessHours = new org.quartz.impl.calendar.DailyCalendar("business-hours", 8, 0, 0, 0, 16, 0, 0, 0); 
businessHours.setInvertTimeRange(true); 

//convert the calendar into a org.drools.time.Calendar 
org.drools.time.Calendar businessHoursCalendar = QuartzHelper.quartzCalendarAdapter(businessHours); 

//Register the calendar in the session with a name. You must use this name in your rules. 
ksession.getCalendars().set("business-hours", businessHoursCalendar); 

Dann in Ihrer Regel müssen Sie schreiben so etwas wie dieses:

rule "Rule X" 
    calendars "business-hours" 
when 
    ... 
then 
    ... 
end 

Hoffe, dass es hilft,

+0

Erstaunlich, das ist genau das, was ich brauche. Vielen Dank für Ihre Mühe! – Gaim

+0

Die 'QuartzHelper' Klasse ist in den neueren Versionen von Drools nicht verfügbar; Wenn Sie es weiterhin verwenden möchten, können Sie es manuell von [hier] herunterladen (http://grepcode.com/file/repository.jboss.org/nexus/content/repositories/releases/org.drools/drools-api/ 5.1.1/org/drools/runtime/hilfe/QuartzHelper.java /). Außerdem wurde 'org.drools.time.Calendar' in neueren Versionen von Drools in' org.kie.api.time.Calendar' geändert. –

0

Gemäß der Dokumentation können Sie Cron Ausdrücke wie Timer verwenden. So könnte man wohl so etwas wie folgt verwenden:

timer(cron: * 8-16 * * 1-5 *) 

Haftungsausschluss: Ich habe das nicht Test!

Hoffnung, es hilft,

+0

Vielen Dank für Ihre Antwort, aber nach der Dokumentation und 'Beispiel 4.29' schätze ich, dass dies die Regel FIRES und das ist nicht was ich will. Ich möchte die Regel aktiv sein, nicht unbedingt gefeuert, während dieser Zeit – Gaim

+0

Hast du es versucht? Ich meine, Regeln werden nur ausgelöst, wenn alle ihre Bedingungen erfüllt sind. Das einzige, was Sie verhindern können, Timer zu verwenden, ist ihre Ausführung. Sie können nicht erzwingen, dass eine Regel ausgeführt wird. –

+0

Dies ist, wie ich denke, es funktioniert: Wenn die Regeln Bedingungen erfüllt sind und Sie sind in einer gültigen Zeit (nach dem Cron-Ausdruck) und Sie FireAllRules() aufrufen, wird Ihre Regel ausgeführt werden. Wenn eine dieser Bedingungen nicht zutrifft, wird die Regel nicht ausgeführt. Es wäre gut, wenn Sie es versuchen könnten, damit wir uns über das Verhalten sicher sein können. –

1

hier eine andere Lösung ist.Vielleicht ein bisschen wie ein Hack, aber es funktioniert:

Sie können eine einfache Java-Klasse erstellen, die die aktuelle Zeit kapselt und eine Instanz dieser Klasse zum Arbeitsspeicher hinzufügen. Diese Klasse, nennen Sie es TimeFact, hat Methoden wie update(long time): void, getDay(): String und getTime(): String. Diese Tatsache kann dann im when Teil einer Regel verwendet werden, wie folgt aus:

rule "Foo" 
when 
    TimeFact(day in ("Monday", "Thursday"), time > "16:00:00" && < "17:00:00") 
    [more conditions] 
then 
    [do stuff] 
end 

Sie die TimeFact (und teilt dies der Regel Motor dieses Update) aktualisieren müssen, bevor Sie Ihre Regeln feuern. Dennoch hat es den Vorteil, dass Regelaktivierungszeiten in den Regeln selbst beschrieben werden können, ohne eine möglicherweise große Anzahl von calendars definieren zu müssen, was diesen Ansatz viel flexibler macht.

Natürlich, wenn Sie nur ein paar solcher Zeitbedingungen haben, wie "Bürozeiten", dann ist die Lösung mit calendars vorzuziehen.

Verwandte Themen