Package pl.net.bluesoft.awf.ext.droolsstep

Source Code of pl.net.bluesoft.awf.ext.droolsstep.DroolsUtils

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.Formats;
import pl.net.bluesoft.util.lang.Mapcar;

import java.io.InputStream;
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 class DroolsResource {
        private String ruleUrl;
        private InputStream ruleStream;

        public DroolsResource(String ruleUrl) {
            this.ruleUrl = ruleUrl;
        }

        public DroolsResource(String ruleUrl, InputStream ruleStream) {
            this.ruleUrl = ruleUrl;
            this.ruleStream = ruleStream;
        }

        public String getRuleUrl() {
            return ruleUrl;
        }

        public InputStream getRuleStream() {
            return ruleStream;
        }
    }

  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<String, Object> globals, DroolsResource... droolsResources) {
        Long timer = System.currentTimeMillis();
        StatefulKnowledgeSession knowledgeSession = getCachedSession(droolsResources);
        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 DroolsResource[] transformRuleUrls(String... rulesUrls) {
        DroolsResource[] resources = new DroolsResource[rulesUrls.length];
        for (int i = 0; i < rulesUrls.length; ++i) {
            resources[i] = new DroolsResource(rulesUrls[i]);
        }
        return resources;
    }

    public static List processRules(List facts, Map<String, Object> globals, String... rulesUrls) {
        return processRules(facts, globals, transformRuleUrls(rulesUrls));
    }

  public static List processRulesWithSession(List facts, Map<String, Object> globals, StatefulKnowledgeSession session) {
    int cnt = 0;
    try {
      while (cnt++ < 10) {
        try {
          for (Map.Entry<String, Object> 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());
        }
        catch (ConcurrentModificationException e) {
          session.dispose();
        }
      }
      throw new RuntimeException("drools failed to initialize session 10 times in a row!");
    }
    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<String, Object> globals, String rulesUrl) {
    StatefulKnowledgeSession session = getCachedSession(rulesUrl);
    try {
      if (session != null) {
                for (Map.Entry<String, Object> e : globals.entrySet()) {
                    session.setGlobal(e.getKey(), e.getValue());
                }
                for (Object o : objects)
                    synchronized (session) {
                        session.insert(o);
                    }
                session.fireAllRules();
                return session.getObjects();
      } else {
        return null;
      }
    }
    finally {
      if (session != null) session.dispose();
    }
  }

  private static final Map<String, KnowledgeBase> BASE_CACHE = new HashMap();
  private static final Map<String, Collection<KnowledgePackage>> PACK_CACHE = new HashMap();
  private static final Map<String, Long> VALIDITY_CACHE = new HashMap();
  private static final Map<String, Long> 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(DroolsResource... droolsResources) {
        KnowledgeBase kb = getCachedKnowledgeBase(droolsResources);
        long t = System.currentTimeMillis();
        try {
            return initSession(kb);
        }
        finally {
            log.fine("initSession took: " + (System.currentTimeMillis() - t));
        }
    }

  public static synchronized StatefulKnowledgeSession getCachedSession(String... rulesUrls) {
        return getCachedSession(transformRuleUrls(rulesUrls));
  }

    private static KnowledgeBase getCachedKnowledgeBase(DroolsResource... droolsResources) {
        List<DroolsResource> resources = Arrays.asList(droolsResources);
        List<String> rules = new Mapcar<DroolsResource, String>(resources) {
            @Override
            public String lambda(DroolsResource x) {
                return x.getRuleUrl();
            }
        }.go();
        Collections.sort(rules);
        String key = Formats.join(rules, ";");

        KnowledgeBase kb;
        synchronized (BASE_CACHE) {
            //nowy sposób, bazujÄ…cy na cache knowledge package a nie knowledge base
            Collection<KnowledgePackage> 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(droolsResources);
                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;
    }

  private static KnowledgeBase getCachedKnowledgeBase(String... rulesUrls) {
        return getCachedKnowledgeBase(transformRuleUrls(rulesUrls));
  }

  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<KnowledgePackage> knowledgePackages = getPackages(rulesUrls);
    return getKbase(knowledgePackages);
  }

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

    private static Collection<KnowledgePackage> getPackages(DroolsResource... droolsResources) {
        MVELDialectConfiguration conf = (MVELDialectConfiguration) new PackageBuilderConfiguration().getDialectConfiguration("mvel");
        conf.setStrict(false);
        conf.getPackageBuilderConfiguration().setDefaultDialect("mvel");

        KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder(conf.getPackageBuilderConfiguration());
        for (DroolsResource res : droolsResources) {
            builder.add(res.getRuleStream() != null ? ResourceFactory.newInputStreamResource(res.getRuleStream())
                    : ResourceFactory.newUrlResource(res.getRuleUrl()), ResourceType.DRL);
        }
        if (builder.hasErrors()) throw new RuntimeException(builder.getErrors().toString());
        Collection<KnowledgePackage> knowledgePackages = builder.getKnowledgePackages();
        return knowledgePackages;
    }

  private static Collection<KnowledgePackage> getPackages(String... rulesUrls) {
        return getPackages(transformRuleUrls(rulesUrls));
  }
}
TOP

Related Classes of pl.net.bluesoft.awf.ext.droolsstep.DroolsUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.