1 package org.kuali.ole.deliver.drools;
2
3 import org.apache.commons.io.FileUtils;
4 import org.apache.commons.io.FilenameUtils;
5 import org.apache.lucene.util.CollectionUtil;
6 import org.drools.core.definitions.rule.impl.RuleImpl;
7 import org.kie.api.KieServices;
8 import org.kie.api.builder.KieBuilder;
9 import org.kie.api.builder.KieFileSystem;
10 import org.kie.api.builder.Message;
11 import org.kie.api.builder.Results;
12 import org.kie.api.definition.KiePackage;
13 import org.kie.api.definition.rule.Rule;
14 import org.kie.api.event.rule.DebugAgendaEventListener;
15 import org.kie.api.runtime.KieContainer;
16 import org.kie.api.runtime.KieSession;
17 import org.kie.internal.io.ResourceFactory;
18 import org.kuali.ole.OLEConstants;
19 import org.kuali.ole.deliver.service.ParameterValueResolver;
20 import org.kuali.ole.sys.context.SpringContext;
21 import org.kuali.rice.core.api.config.property.ConfigContext;
22 import org.kuali.rice.coreservice.api.parameter.Parameter;
23 import org.kuali.rice.coreservice.api.parameter.ParameterType;
24 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import java.io.File;
29 import java.util.*;
30
31
32
33
34 public class DroolsKieEngine {
35 private Logger LOG = LoggerFactory.getLogger(DroolsKieEngine.class);
36 private KieContainer kieContainer;
37 private ParameterService parameterService;
38
39 private static Boolean forceLoadPolicies = true;
40 private static final String LOAD_POLICIES_IND = "LOAD_CIRC_POLICIES_IND";
41
42 private static DroolsKieEngine droolsEngine = new DroolsKieEngine();
43
44 protected DroolsKieEngine() {
45
46 }
47
48 public static DroolsKieEngine getInstance() {
49 return droolsEngine;
50 }
51
52
53
54
55 public void initKnowledgeBase() {
56 long startTime = System.currentTimeMillis();
57 populateKnowledgeBase();
58 long endTime = System.currentTimeMillis();
59 System.out.println("Time taken to populate drools knowledgebase: " + (endTime - startTime) + " ms");
60 }
61
62 private void populateKnowledgeBase() {
63 Boolean parameterValueAsBoolean = getParameterAsBoolean();
64 if (forceLoadPolicies || parameterValueAsBoolean) {
65 readRules();
66 updateParameter();
67 }
68 }
69
70 private Boolean getParameterAsBoolean() {
71 return ParameterValueResolver.getInstance().getParameterAsBoolean(OLEConstants
72 .APPL_ID, OLEConstants
73 .DLVR_NMSPC,
74 OLEConstants
75 .DLVR_CMPNT, LOAD_POLICIES_IND);
76 }
77
78 private void updateParameter() {
79 Parameter existingParameter = getParameterService().getParameter(OLEConstants.DLVR_NMSPC, OLEConstants
80 .DLVR_CMPNT, LOAD_POLICIES_IND);
81 if (existingParameter != null) {
82 Parameter.Builder updatedParameter = Parameter.Builder.create(existingParameter);
83 updatedParameter.setValue("N");
84 forceLoadPolicies = false;
85 getParameterService().updateParameter(updatedParameter.build());
86 } else {
87 Parameter.Builder newParameter = Parameter.Builder.create(OLEConstants.APPL_ID, OLEConstants.DLVR_NMSPC, OLEConstants.DLVR_CMPNT, LOAD_POLICIES_IND, ParameterType.Builder.create("CONFG"));
88 newParameter.setDescription("Set to 'Y' to have the application ingest the default circulation policies " +
89 "upon next policy evaluation.");
90 newParameter.setValue("Y");
91 getParameterService().createParameter(newParameter.build());
92 forceLoadPolicies = false;
93 }
94 }
95
96 private void readRules() {
97
98 File rulesDirectory = FileUtils.getFile(getRulesDirectory());
99 if (null != rulesDirectory && rulesDirectory.isDirectory() && FileUtils.sizeOfDirectory(rulesDirectory) > 0) {
100 File[] files = rulesDirectory.listFiles();
101
102 KieServices kieServices = KieServices.Factory.get();
103 KieFileSystem kfs = kieServices.newKieFileSystem();
104
105 loadRules(kfs, files);
106
107 KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
108 Results results = kieBuilder.getResults();
109
110 if (results.hasMessages(Message.Level.ERROR)) {
111
112 }
113
114 long startTime = System.currentTimeMillis();
115 kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
116 long endTime = System.currentTimeMillis();
117 System.out.println("Time taken to initiallize KieContainer: " + (endTime - startTime) + "ms");
118
119
120 } else {
121 LOG.error("Could not load Circulation Rules as directory doest not exist or is unreadable.");
122 }
123 }
124
125 private void loadRules(KieFileSystem kfs, File[] files) {
126 for (int i = 0; i < files.length; i++) {
127 File file = files[i];
128 if (!file.isDirectory()) {
129 if (FilenameUtils.getExtension(file.getName()).equals("drl")) {
130 kfs.write(ResourceFactory.newFileResource(file));
131 }
132 } else {
133 File[] subDirFiles = file.listFiles();
134 loadRules(kfs, subDirFiles);
135 }
136 }
137 }
138
139 public synchronized void disposeSession(KieSession kieSession) {
140 kieSession.dispose();
141 }
142
143 public String getRulesDirectory() {
144 String rulesDirectory = ConfigContext.getCurrentContextConfig().getProperty("rules.directory");
145 return rulesDirectory;
146 }
147
148 public synchronized KieSession getSession() {
149 populateKnowledgeBase();
150 long startTime1 = System.currentTimeMillis();
151 KieSession kieSession = kieContainer.newKieSession();
152 kieSession.addEventListener(new CustomAgendaEventListener());
153 kieSession.addEventListener(new DebugAgendaEventListener());
154 long endTime1 = System.currentTimeMillis();
155
156 System.out.println("Time taken to initialize KieSession: " + (endTime1 - startTime1) + "ms");
157
158 return kieSession;
159
160 }
161
162 public ParameterService getParameterService() {
163 if (null == parameterService) {
164 parameterService = SpringContext.getBean(ParameterService.class);
165 }
166 return parameterService;
167 }
168
169 public void setParameterService(ParameterService parameterService) {
170 this.parameterService = parameterService;
171 }
172
173
174 public List<String> getRulesByAgendaGroup(List<String>agendaGroups){
175 List<String> ruleNames = new ArrayList<>();
176
177 for (Iterator iterator = kieContainer.getKieBase().getKiePackages().iterator(); iterator.hasNext(); ) {
178 KiePackage kiePackage = (KiePackage) iterator.next();
179 Collection<Rule> rules = kiePackage.getRules();
180 for (Iterator<Rule> ruleIterator = rules.iterator(); ruleIterator.hasNext(); ) {
181 Rule rule = ruleIterator.next();
182 if(agendaGroups.contains(((RuleImpl)rule).getAgendaGroup())){
183 ruleNames.add(rule.getName());
184 }
185 }
186 }
187 Collections.sort(ruleNames);
188 return ruleNames;
189 }
190
191
192 public List<String> getAllLoadedRules(){
193 List<String> ruleNames = new ArrayList<>();
194
195 for (Iterator iterator = kieContainer.getKieBase().getKiePackages().iterator(); iterator.hasNext(); ) {
196 KiePackage kiePackage = (KiePackage) iterator.next();
197 Collection<Rule> rules = kiePackage.getRules();
198 for (Iterator<Rule> ruleIterator = rules.iterator(); ruleIterator.hasNext(); ) {
199 Rule rule = ruleIterator.next();
200 ruleNames.add(rule.getName());
201 }
202 }
203
204 return ruleNames;
205 }
206 }