Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

...

Facilities
FacilityIdOrganizationIdNameTimezoneNFCEnabledNFCSelfModificationEnabledBarCodeEnabled
ACME-PHACME

 Pearl Harbor

US/Hawaii

truefalsefalse

...

SurveyTemplates
SurveyIdName
1New Line Report
2Line Maintenance
3Infection Report
4Breast Milk Report
5Patient Demographics
6Patient Discharge
7Patient Open Lines
8Form Open Lines
9Admission Questions
10Patient Final Discharge
11AUDIT
12MDQ

7. Organization's Alerts

7.1 SurveyAgent

Remember that Alerts are generated by the SurveyAgent. For this scenario we are going to have 2 rules generating alerts: 'New Patient Admission" and "Milk Importance Not Discussed".

...

Code Block
languagejava
linenumberstrue
package org.socraticgrid.survey.agent;
import org.drools.mas.body.content.*;
import org.drools.mas.action.message.*;
import org.drools.mas.action.message.types.*;
import org.drools.mas.action.message.invokers.*;
import org.socraticgrid.survey.agent.api.model.SurveySubmissionFact;
import org.socraticgrid.survey.agent.api.model.SurveySubmissionAnswerFact;
import org.socraticgrid.survey.agent.api.model.PreValidationResult;
import org.socraticgrid.survey.agent.log.RulesLoggerHelper;
import org.socraticgrid.surveys.model.*;
import org.socraticgrid.surveys.service.SurveyService;
import org.socraticgrid.alertmanager.service.AlertService;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Date;
import org.drools.mas.action.helpers.*;
/* Global Services */
global SurveyService surveyService;
global AlertService alertService;
global Logger logger;
 
rule "New Patient Admission"
when
    //There is a Submission of a #5 Survey
    //And there alert was not previously sent.
    $s: SurveySubmissionFact(
            surveyId == 5,
            $chartId: q["q008"],
            alertService.parameterizedAlertExists($s.getPatientId(), "New Patient Admission") == false
    )
then
    RulesLoggerHelper.debug(logger, drools, "New Admission detected: {}", $s);

    templateVariables.put("common_patient_chartId", $chartId);
    insert( new ResolvableActionAgentNotificationCandidateFact(
        drools.getRule().getName(),     //sourceRule
        "ADMISSION",                          //sourceProgram
        (SurveySubmissionFact)$s,       //sourceFact
        $s.getPatientId(),                      //sourcePatient
        "HIGH",                                     //priority
        "ACME-NewAdmission",                   //template
        "10s",                                        //timeout
        templateVariables                     //template variables
));
end

rule "Milk Importance Not Discussed"
when
    //There is a Submission of a #4 Survey
    $s: SurveySubmissionFact(
            surveyId == 4,
            q["q007"] == "No"
    )
then
    RulesLoggerHelper.debug(logger, drools, "Milk Importance Not Discussed: {}", $s);
    insert( new ResolvableActionAgentNotificationCandidateFact(
        drools.getRule().getName(),     //sourceRule
        "NCCC",                                    ///sourceProgram
        (SurveySubmissionFact)$s,       //sourceFact
        $s.getPatientId(),                      //sourcePatient
        "HIGH",                                     //priority
        "ACME-NotDiscussed",            //template
        "10s",                                        //timeout
        null                            //template  variables
 ));
          //template variables
));
end

...

end

Some important notes about ACME-alerts.drl are:

  • Lines #25 and #50 define the 2 rules
  • In "New Patient Admission" rule (the other rule is similar):
    • Line #35 logs information
    • Line #37 inserts a new ResolvableActionNotificationCandidateFact that will end up notifying the ActionAgent about a new Alert.
    • Line #44 specifies the Template id that we want to use. Templates and their Ids are defined in the ActionAgent.

The next step is to create a change-set that includes all the necessary .drl files. Let's call this file ACME-change-set.xml.

 

Code Block
languagexml
linenumberstrue
<?xml version="1.0" encoding="UTF-8"?>
<change-set xmlns='http://drools.org/drools-5.0/change-set' xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'
xs:schemaLocation='http://drools.org/drools-5.0/change-set http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd'>
    <add>
        <resource type="DRL" source="classpath:org/drools/mas/acl_common.drl" />
        <resource type="DRL" source="classpath:knowledge/subsession/subsession-config.drl" />
        <resource type="DRL" source="classpath:knowledge/subsession/survey-common.drl" />
        <resource type="DRL" source="classpath:knowledge/subsession/survey-prevalidation-common.drl" />
        <resource type="DRL" source="classpath:knowledge/subsession/survey-alert-common.drl" />
        <resource type="DRL" source="classpath:knowledge/subsession/ACME-alerts.drl" />
    </add>
</change-set>

Some important notes about the change-set:

  • From line #5 to line #9 we have some common .drl that should be included in any session.
  • Line #10 includes the .drl we have specifically created for ACME organization.

 

Once we have the rules and the change-set we need to define a new sub-session for ACME in applicationContext.xml file:

Code Block
languagexml
linenumberstrue
<bean id="ACME" class="org.drools.mas.core.DroolsAgentConfiguration$SubSessionDescriptor">
    <constructor-arg value="subsession-acme"/>
    <constructor-arg value="ACME-change-set.xml"/>
    <constructor-arg value="${agent.node}"/>
    <constructor-arg>
        <map>
            <entry key="organizationId" value="ACME"/>
        </map>
    </constructor-arg>
</bean>
...
<bean id="${agent.name}-configuration" class="org.drools.mas.core.DroolsAgentConfiguration">
    <property name="agentId" value="${agent.name}"/>
    <property name="changeset" value="agent_changeset.xml" />
    <!-- by default the mindNodeLocation is local --> 
    <property name="mindNodeLocation" value="${agent.node}"/>
    <property name="subSessions">
        <list>
            ...
            <ref local="${agent.name}-unc"/>
        </list>
    </property>
</bean>

Important notes about the contextApplication.xml file:

  • Line #1 defines the new sub-session for ACME organization.
  • Line #20 includes this new sub-session as part of the main session of the agent.

The last step is to add the routing statement in agent_cbr.drl:

Code Block
languagejava
linenumberstrue
rule "Mapping"
when
then
    ...
    insert( new SessionMapping("ACME","subsession-acme") );
    RulesLoggerHelper.debug(logger, drools, "Subsession mapping created for 'ACME');
    ... 
end

7.2 Alerts Configuration

AlertConfiguration
IdNameDescriptionAlertKeyWorkspaceIdSendNotification
1  New Patient AdmissionPH-NurseryTrue
2  Milk Importance Not DiscussedPH-NurseryTrue
3  New Patient AdmissionPH-NicuTrue
4  Milk Importance Not DiscussedPH-NicuTrue
AlertConfigurationUserRecipient
IdAlertConfigurationIdUserId
1 1 ACME-U1
2 3 ACME-U1
AlertConfigurationRoleRecipient
IdAlertConfigurationIdRoleId
1 2 2
2 4 2