All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pl.net.bluesoft.awf.ext.droolsstep.DroolsUtils Maven / Gradle / Ivy

package pl.net.bluesoft.awf.ext.droolsstep;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.compiler.PackageBuilderConfiguration;
import org.drools.definition.KnowledgePackage;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.rule.builder.dialect.mvel.MVELDialectConfiguration;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.StatelessKnowledgeSession;
import pl.net.bluesoft.util.lang.FormatUtil;

import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class DroolsUtils {
	private static final Logger log = Logger.getLogger(DroolsUtils.class.getName());


	public static List processRules(List facts, String... rulesUrl) {
		Long timer = System.currentTimeMillis();
		List res = processRules("result", facts, rulesUrl);
		log.fine("Timing [processing drools rules]. Duration: " + (System.currentTimeMillis() - timer) + "ms");
		return res;
	}

	public static List processRules(String rulesUrl, List objects) {
		return processRules("result", objects, rulesUrl);
	}

	public static List processRulesStafeful(String rulesUrl, List objects) {
		final List res = new ArrayList();

		HashMap map = new HashMap();
		map.put("result", res);
		processCachedRulesAndReturnFacts(objects, map, rulesUrl);
		return res;
	}

    public static List processRules(List facts, Map globals, String... rulesUrls) {
	    Long timer = System.currentTimeMillis();
	    StatefulKnowledgeSession knowledgeSession = getCachedSession(rulesUrls);
        try {
	        log.fine("Timing [getting session]. Duration: " + (System.currentTimeMillis() - timer) + "ms");	        
	        return processRulesWithSession(facts, globals, knowledgeSession);
        }
        catch (RuntimeException e) {
            //clear rule cache
            PACK_CACHE.clear();
            BASE_CACHE.clear();
            throw e;
        }
        finally {
            knowledgeSession.dispose();
	        log.fine("Timing [process rules]. Duration: " + (System.currentTimeMillis() - timer) + "ms");	        	        
        }
    }

	public static List processRulesWithSession(List facts, Map globals, StatefulKnowledgeSession session) {
		try {
            for (Map.Entry e : globals.entrySet()) {
                session.setGlobal(e.getKey(), e.getValue());
            }
            for (Object o : facts) {
                synchronized (session) {
                    session.insert(o);
                }
            }
            session.fireAllRules();
            return new ArrayList(session.getObjects());
		} finally {
		    session.dispose();
		}
	}


	private static List processRules(final String resultName, List objects, String... rulesUrls) {
		final List result = new ArrayList();
		HashMap map = new HashMap();
		map.put(resultName, result);
		processRules(objects, map, rulesUrls);
		return result;
	}

	public static Collection processCachedRulesAndReturnFacts(List objects, Map globals,                                                      String rulesUrl) {
		StatefulKnowledgeSession session = getCachedSession(rulesUrl);
        if (session != null) {
            try {
                for (Map.Entry e : globals.entrySet()) {
                    session.setGlobal(e.getKey(), e.getValue());
                }
                for (Object o : objects) {
                    synchronized (session) {
                        session.insert(o);
                    }
                    session.fireAllRules();
                }
                return session.getObjects();
            } finally {
                session.dispose();
            }
        }
        return null;
	}

	private static final Map BASE_CACHE = new HashMap();
	private static final Map> PACK_CACHE = new HashMap();
	private static final Map VALIDITY_CACHE = new HashMap();
	private static final Map PACK_VALIDITY_CACHE = new HashMap();
	private static final long VALIDITY_TIME = 15 * 60 * 1000; 
	private static final long PACK_VALIDITY_TIME = 60 * 60 * 1000; //1 godzina

	public static synchronized StatefulKnowledgeSession getCachedSession(String... rulesUrls) {
		KnowledgeBase kb = getCachedKnowledgeBase(rulesUrls);
		long t = System.currentTimeMillis();
		try {
			return initSession(kb);
		}
		finally {
			log.fine("initSession took: " + (System.currentTimeMillis() - t));
		}
	}

	private static KnowledgeBase getCachedKnowledgeBase(String... rulesUrls) {
		List rules = new LinkedList(Arrays.asList(rulesUrls));
		Collections.sort(rules);
		String key = FormatUtil.join(rules, ";");

		KnowledgeBase kb;
		synchronized (BASE_CACHE) {
            // new way, use cache for KnowledgePackage and not for entire KnowledgeBase
			Collection knowledgePackages = PACK_CACHE.get(key);

			kb = BASE_CACHE.get(key);
			Long validTo = VALIDITY_CACHE.get(key);
			if (validTo != null && validTo < System.currentTimeMillis()) {
				log.warning("clearing cache for " + key);
				kb = null;
			}

			validTo = PACK_VALIDITY_CACHE.get(key);
			if (validTo != null && validTo < System.currentTimeMillis()) {
				log.warning("clearing packages cache for " + key);
				kb = null;
				knowledgePackages = null;
			}
			
			if (knowledgePackages == null) {
				knowledgePackages = getPackages(rulesUrls);
				PACK_CACHE.put(key, knowledgePackages);
				PACK_VALIDITY_CACHE.put(key, System.currentTimeMillis() + PACK_VALIDITY_TIME);				
				log.warning("registering drools packages for " + key);
			} else {
				log.fine("found cached drools packages for " + key);
			}
			if (kb == null) {
				kb = getKbase(knowledgePackages);
				BASE_CACHE.put(key, kb);
				VALIDITY_CACHE.put(key, System.currentTimeMillis() + VALIDITY_TIME);
				log.warning("registering KnowledgeBase for " + key);
			} else {
				log.fine("found cached KnowledgeBase for " + key);
			}
		}
		return kb;
	}

	public static synchronized StatelessKnowledgeSession getCachedStatelessSession(String... rulesUrls) {
		KnowledgeBase kb = getCachedKnowledgeBase(rulesUrls);
		long t = System.currentTimeMillis();
		try {
			return initStatelessSession(kb);
		}
		finally {
			log.fine("initStatelessSession took: " + (System.currentTimeMillis() - t));
		}
	}

	public synchronized static StatefulKnowledgeSession getSession(String... rulesUrls) {
		KnowledgeBase kbase = getKbase(rulesUrls);
		return initSession(kbase);
	}

	private static StatefulKnowledgeSession initSession(KnowledgeBase kbase) {
		StatefulKnowledgeSession session = null;
		if (kbase != null) {
			synchronized (kbase) {
				session = kbase.newStatefulKnowledgeSession();
			}
		}
		return session;
	}

	private static StatelessKnowledgeSession initStatelessSession(KnowledgeBase kbase) {
		StatelessKnowledgeSession session = null;
		if (kbase != null) {
			synchronized (kbase) {
				session = kbase.newStatelessKnowledgeSession();
				if (log.isLoggable(Level.FINEST)) {
					KnowledgeRuntimeLoggerFactory.newConsoleLogger(session);
                }
			}
		}
		return session;
	}

	private static KnowledgeBase getKbase(String... rulesUrls) {
		Collection knowledgePackages = getPackages(rulesUrls);
		return getKbase(knowledgePackages);
	}

	private static KnowledgeBase getKbase(Collection knowledgePackages) {
		KnowledgeBase kbase = null;
		if (!knowledgePackages.isEmpty()) {
			kbase = KnowledgeBaseFactory.newKnowledgeBase();
			kbase.addKnowledgePackages(knowledgePackages);
		}
		return kbase;
	}

	private static Collection getPackages(String... rulesUrls) {
		MVELDialectConfiguration conf = (MVELDialectConfiguration) new PackageBuilderConfiguration().getDialectConfiguration("mvel");
		conf.setStrict(false);
		conf.getPackageBuilderConfiguration().setDefaultDialect("mvel");

		KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder(conf.getPackageBuilderConfiguration());
		for (String rulesUrl : rulesUrls) {
			builder.add(ResourceFactory.newUrlResource(rulesUrl), ResourceType.DRL);
		}
		if (builder.hasErrors()) throw new RuntimeException(builder.getErrors().toString());
		Collection knowledgePackages = builder.getKnowledgePackages();
		return knowledgePackages;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy