[jboss-svn-commits] JBL Code SVN: r17507 - in labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services: rules and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Jan 2 19:52:23 EST 2008


Author: jeffdelong
Date: 2008-01-02 19:52:23 -0500 (Wed, 02 Jan 2008)
New Revision: 17507

Added:
   labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/
   labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleBaseHelper.java
   labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java
   labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceException.java
   labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceFactory.java
Log:


Added: labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleBaseHelper.java
===================================================================
--- labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleBaseHelper.java	                        (rev 0)
+++ labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleBaseHelper.java	2008-01-03 00:52:23 UTC (rev 17507)
@@ -0,0 +1,228 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.internal.soa.esb.services.rules;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+
+import org.apache.log4j.Logger;
+import org.drools.RuleBase;
+import org.drools.RuleBaseConfiguration;
+import org.drools.RuleBaseConfiguration.AssertBehaviour;
+import org.drools.RuleBaseFactory;
+import org.drools.agent.RuleAgent;
+import org.drools.compiler.DroolsParserException;
+import org.drools.compiler.PackageBuilder;
+import org.drools.compiler.PackageBuilderConfiguration;
+import org.drools.decisiontable.InputType;
+import org.drools.decisiontable.SpreadsheetCompiler;
+import org.drools.rule.Package;
+import org.jboss.soa.esb.util.ClassUtil;
+
+/**
+ * A helper class, it returns rulebases based on various methods of creating them
+ * 
+ * @author jdelong at redhat.com
+ * 
+ */
+public class DroolsRuleBaseHelper {
+
+	private static Logger logger = Logger.getLogger(DroolsRuleBaseHelper.class);
+
+	/**
+	 * Creates a rulebase using rules and dsl from files. Note the dsl may be null.
+	 */
+	public RuleBase createRuleBaseFromRuleFiles(String ruleFile, String dsl)
+			throws DroolsParserException, IOException, RuleServiceException {
+		// read in the rules
+		logger.debug("Going to create a rulebase from the ruleFile: "
+				+ ruleFile);
+		InputStream rulesInputStream = getRulesInputStream(ruleFile);
+
+		if (rulesInputStream == null) {
+			logger.error("Could not find ruleFile: " + ruleFile);
+			return null;
+		} else {
+			Reader ruleReader = getRulesReader(rulesInputStream);
+
+			PackageBuilderConfiguration pkgBuilderCfg = new PackageBuilderConfiguration();
+			//pkgBuilderCfg.setCompiler(PackageBuilderConfiguration.JANINO);
+			PackageBuilder builder = new PackageBuilder(pkgBuilderCfg);
+			try {
+				if (dsl == null) {
+					builder.addPackageFromDrl(ruleReader);
+				} else {
+					logger.debug("Going to read the dsl: " + dsl);
+					InputStream dslInputStream = getRulesInputStream(dsl);
+					Reader dslReader = getRulesReader(dslInputStream);
+					if (dslReader == null) {
+						logger.error("Could not find dsl: " + ruleFile);
+					} else {
+						try {
+							builder.addPackageFromDrl(ruleReader, dslReader);
+						} finally {
+							safeClose(dslInputStream);
+						}
+					}
+				}
+			} finally {
+				safeClose(rulesInputStream);
+			}
+
+			// get the compiled package (which is serializable)
+			Package pkg = builder.getPackage();
+			// add the package to a rulebase
+			try {
+				RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+				ruleBase.addPackage(pkg);
+				return ruleBase;
+			} catch (Exception ex) {
+				throw new RuleServiceException(ex.getMessage(), ex);
+			}
+		}
+	}
+
+	/**
+	 * Reading the rules and dsl from files and returning as a string
+	 * to compare them for changes. Note the dsl may be null.
+	 */
+	public String getRulesAsString(String ruleFile, String dsl)
+			throws IOException {
+		logger.debug("Going to hash the rule: " + ruleFile);
+		InputStream rulesInputStream = getRulesInputStream(ruleFile);
+		if (rulesInputStream == null) {
+			logger.error("Could not find ruleFile: " + ruleFile);
+			return null;
+		} else {
+			final String rules;
+			try {
+				rules = getString(rulesInputStream);
+			} finally {
+				safeClose(rulesInputStream);
+			}
+			String language = "";
+			if (dsl != null) {
+				logger.debug("Going to hash the language: " + dsl);
+				InputStream dslInputStream = getRulesInputStream(dsl);
+				if (dslInputStream == null) {
+					logger.error("Could not find language: " + dsl);
+				} else {
+					try {
+						language = getString(dslInputStream);
+					} finally {
+						safeClose(dslInputStream);
+					}
+				}
+			}
+			return rules + language;
+		}
+
+	}
+
+	private Reader getRulesReader(InputStream inputStream) {
+		return new InputStreamReader(inputStream);
+	}
+
+	private InputStream getRulesInputStream(String rulesFile) {
+		return ClassUtil.getResourceAsStream("/" + rulesFile,
+				DroolsRuleBaseHelper.class);
+	}
+
+	/**
+	 * Reading the rules and dsl from files. Note the dsl may be null.
+	 */
+	public RuleBase createRuleBaseFromDecisionTable(String decisionTable)
+			throws DroolsParserException, IOException, RuleServiceException {
+		logger.debug("Going to read the decisionTable: " + decisionTable);
+		String drl = getSpreadsheetRules(decisionTable);
+		PackageBuilder builder = new PackageBuilder();
+		builder.addPackageFromDrl(new StringReader(drl));
+		try {
+			//add the package to a rulebase (deploy the rule package).
+			RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+			ruleBase.addPackage(builder.getPackage());
+			return ruleBase;
+		} catch (Exception ex) {
+			throw new RuleServiceException(ex.getMessage(), ex);
+		}
+	}
+
+	/**
+	 * Reading the decision table and creating a drl
+	 */
+	public String getSpreadsheetRules(String decisionTable) {
+		logger.debug("Going to read the decisionTable: " + decisionTable);
+		String drl;
+		InputStream inputStreamDT = ClassUtil.getResourceAsStream("/"
+				+ decisionTable, DroolsRuleBaseHelper.class);
+		if (inputStreamDT == null) {
+			logger.error("Could not find decisionTable: " + decisionTable);
+			return null;
+		} else {
+			SpreadsheetCompiler compiler = new SpreadsheetCompiler();
+
+			try {
+				drl = compiler.compile(inputStreamDT, InputType.XLS);
+				logger.debug("Compiled the decsionTable to a drl: " + drl);
+			} finally {
+				safeClose(inputStreamDT);
+			}
+			return drl;
+		}
+
+	}
+
+	/**
+	 * This shows how rules are loaded up from a deployed package.
+	 */
+	public RuleBase loadRuleBaseFromRuleAgent(String ruleAgentProperties)
+			throws IOException, Exception {
+
+		logger.debug("Going to read the ruleAgentProperties: "
+				+ ruleAgentProperties);
+		RuleAgent agent = RuleAgent.newRuleAgent("/" + ruleAgentProperties);
+		RuleBase rb = agent.getRuleBase();
+
+		return rb;
+	}
+
+	
+	private static void safeClose(final InputStream is) {
+		try {
+			is.close();
+		} catch (final Throwable th) {
+		} // ignore
+	}
+
+	private static String getString(InputStream in) throws IOException {
+		StringBuffer stringBuffer = new StringBuffer();
+		byte[] b = new byte[4096];
+		for (int i; (i = in.read(b)) != -1;) {
+			stringBuffer.append(new String(b, 0, i));
+		}
+		return stringBuffer.toString();
+	}
+
+}

Added: labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java
===================================================================
--- labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java	                        (rev 0)
+++ labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java	2008-01-03 00:52:23 UTC (rev 17507)
@@ -0,0 +1,783 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.internal.soa.esb.services.rules;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.Level;
+import org.drools.RuleBase;
+import org.drools.StatefulSession;
+import org.drools.StatelessSession;
+import org.drools.compiler.DroolsParserException;
+import org.jboss.internal.soa.esb.services.routing.cbr.JBRulesCounter;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.lifecycle.LifecyclePriorities;
+import org.jboss.soa.esb.lifecycle.LifecycleResource;
+import org.jboss.soa.esb.lifecycle.LifecycleResourceException;
+import org.jboss.soa.esb.lifecycle.LifecycleResourceFactory;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.services.rules.RuleService;
+
+/**
+ * The Implementation of a rule engine interface for rules services. Here we use
+ * JBossRules (aka Drools). We keep a HashMap of stateful session working
+ * memories.
+ * 
+ * @author jdelong at redhat.com
+ * 
+ */
+public class DroolsRuleService implements RuleService {
+
+	/**
+	 * The lifecycle resource factory.
+	 */
+	private static final LifecycleResourceFactory<Map<String, RuleBase>> lifecycleRuleBaseFactory = new LifecycleRuleBaseFactory();
+	/**
+	 * Lifecycle couriers.
+	 */
+	private static final LifecycleResource<Map<String, RuleBase>> lifecycleRuleBases = new LifecycleResource<Map<String, RuleBase>>(
+			lifecycleRuleBaseFactory, LifecyclePriorities.RULE_BASE_PRIORITY);
+	/**
+	 * The lifecycle resource factory.
+	 */
+	private static final LifecycleResourceFactory<Map<String, String>> lifecycleRuleSetFactory = new LifecycleRuleSetFactory();
+	/**
+	 * Lifecycle couriers.
+	 */
+	private static final LifecycleResource<Map<String, String>> lifecycleRuleSets = new LifecycleResource<Map<String, String>>(
+			lifecycleRuleSetFactory, LifecyclePriorities.RULE_BASE_PRIORITY);
+
+	private static Logger logger = Logger.getLogger(DroolsRuleService.class);
+
+	private JBRulesCounter rulesCounter = null;
+
+	/**
+	 * Execute rules using a certain ruleSet and domain specific language using
+	 * the Stateless rule engine API
+	 * 
+	 * @param ruleSet -
+	 *            String reference to a file which contains a ruleSet.
+	 * @param dsl -
+	 *            String reference to a file which contains a custom rule
+	 *            language definition
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading
+	 *            the ruleSet.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList -
+	 *            a list with additional objects (typically pulled from the
+	 *            message) to be inserted into working memory
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatelessRules(String ruleSet, String dsl,
+			boolean ruleReload, Message message, List<Object> objectList)
+			throws RuleServiceException
+
+	{
+		long startTime = System.nanoTime();
+
+		try {
+			RuleBase ruleBase = getRuleBaseForFileBasedRules(ruleSet, dsl,
+					ruleReload);
+			message = executeStatelessRules(ruleBase, message, objectList);
+
+			long procTime = System.nanoTime() - startTime;
+			if (rulesCounter != null) {
+				rulesCounter.update(procTime, ruleSet,
+						JBRulesCounter.RULES_SUCCEED);
+			}
+
+			return message;
+
+		} catch (RuleServiceException ree) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, ruleSet,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not parse the rules. "
+					+ ree.getMessage(), ree);
+		}
+	}
+
+	/**
+	 * Execute rules from a decision table using the Stateless rule engine API
+	 * 
+	 * @param decisionTable -
+	 *            String reference to a file which contains a spreadsheet of rules
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading
+	 *            the ruleSet.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatelessRulesFromDecisionTable(String decisionTable,
+			boolean ruleReload, Message message, List<Object> objectList)
+			throws RuleServiceException {
+		long startTime = System.nanoTime();
+
+		try {
+			RuleBase ruleBase = getRuleBaseForDecisionTable(decisionTable,
+					ruleReload);
+			message = executeStatelessRules(ruleBase, message, objectList);
+
+			long procTime = System.nanoTime() - startTime;
+			if (rulesCounter != null) {
+				rulesCounter.update(procTime, decisionTable,
+						JBRulesCounter.RULES_SUCCEED);
+			}
+
+			return message;
+
+		} catch (RuleServiceException ree) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, decisionTable,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not parse the rules. "
+					+ ree.getMessage(), ree);
+		}
+	}
+
+	/**
+	 * Execute rules using a rule package retrieved via the Rule Agent from a URL of local file system
+	 *            using the Stateless rule engine API
+	 * 
+	 * @param ruleAgentProperties -
+	 *            String reference to a file which contains properties used by the RuleAgent to locate a rule package.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatelessRulesFromRuleAgent(
+			String ruleAgentProperties, Message message, List<Object> objectList)
+			throws RuleServiceException {
+		long startTime = System.nanoTime();
+		try {
+			DroolsRuleBaseHelper rbHelper = new DroolsRuleBaseHelper();
+			RuleBase ruleBase = rbHelper
+					.loadRuleBaseFromRuleAgent(ruleAgentProperties);
+			final Map<String, RuleBase> ruleBases = lifecycleRuleBases
+					.getLifecycleResource();
+			if (ruleBase != null) {
+				ruleBases.put(ruleAgentProperties, ruleBase);
+
+				message = executeStatelessRules(ruleBase, message, objectList);
+
+				long procTime = System.nanoTime() - startTime;
+				if (rulesCounter != null) {
+					rulesCounter.update(procTime, ruleAgentProperties,
+							JBRulesCounter.RULES_SUCCEED);
+				}
+			}
+
+			return message;
+
+		} catch (IOException ioe) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, ruleAgentProperties,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException(
+					"Could not read the ruleAgentProperties. "
+							+ ioe.getMessage(), ioe);
+		} catch (RuleServiceException ree) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, ruleAgentProperties,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not parse the rules. "
+					+ ree.getMessage(), ree);
+		} catch (Exception e) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, ruleAgentProperties,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException(
+					"RuleAgent could not get the RuleBase. " + e.getMessage(),
+					e);
+		}
+
+	}
+
+	/**
+	 * Execute rules using a certain ruleSet and domain specific language using the Stateful rule engine API
+	 * 
+	 * @param ruleSet -
+	 *            String reference to a file which contains a ruleSet.
+	 * @param domainSpecificLanguage -
+	 *            String reference to a file which contains a custom rule
+	 *            language definition
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading
+	 *            the ruleSet.
+	 * @param dispose -
+	 *            if set to true, working memory will be disposed after the rules are fired
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatefulRules(String ruleSet, String dsl,
+			boolean ruleReload, boolean dispose, Message message,
+			List<Object> objectList) throws RuleServiceException {
+		long startTime = System.nanoTime();
+
+		try {
+			RuleBase ruleBase = getRuleBaseForFileBasedRules(ruleSet, dsl,
+					ruleReload);
+			message = executeStatefulRules(ruleBase, dispose, message,
+					objectList);
+
+			long procTime = System.nanoTime() - startTime;
+			if (rulesCounter != null) {
+				rulesCounter.update(procTime, ruleSet,
+						JBRulesCounter.RULES_SUCCEED);
+			}
+
+			return message;
+
+		} catch (RuleServiceException ree) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, ruleSet,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not parse the rules. "
+					+ ree.getMessage(), ree);
+		}
+	}
+
+	/**
+	 * Execute rules from a decision table using the Stateful rule engine API
+	 * 
+	 * @param decisionTable -
+	 *            String reference to a file which contains a spreadsheet of rules
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading
+	 *            the ruleSet.
+	 * @param dispose -
+	 *            if set to true, working memory will be disposed after the rules are fired
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatefulRulesFromDecisionTable(String decisionTable,
+			boolean ruleReload, boolean dispose, Message message,
+			List<Object> objectList) throws RuleServiceException {
+		long startTime = System.nanoTime();
+
+		try {
+			RuleBase ruleBase = getRuleBaseForDecisionTable(decisionTable,
+					ruleReload);
+			message = executeStatefulRules(ruleBase, dispose, message,
+					objectList);
+
+			long procTime = System.nanoTime() - startTime;
+			if (rulesCounter != null) {
+				rulesCounter.update(procTime, decisionTable,
+						JBRulesCounter.RULES_SUCCEED);
+			}
+
+			return message;
+
+		} catch (RuleServiceException ree) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, decisionTable,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not parse the rules. "
+					+ ree.getMessage(), ree);
+		}
+	}
+
+	/**
+	 * Execute rules using a rule package retrieved via the Rule Agent from a URL of local file system
+	 *            using the Stateful rule engine API
+	 * 
+	 * @param ruleAgentProperties -
+	 *            String reference to a file which contains properties used by the RuleAgent to locate a rule package.
+	 * @param dispose -
+	 *            if set to true, working memory will be disposed after the rules are fired
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatefulRulesFromRuleAgent(
+			String ruleAgentProperties, boolean dispose, Message message,
+			List<Object> objectList) throws RuleServiceException {
+		long startTime = System.nanoTime();
+		try {
+			DroolsRuleBaseHelper rbHelper = new DroolsRuleBaseHelper();
+			RuleBase ruleBase = rbHelper
+					.loadRuleBaseFromRuleAgent(ruleAgentProperties);
+
+			final Map<String, RuleBase> ruleBases = lifecycleRuleBases
+					.getLifecycleResource();
+			if (ruleBase != null) {
+				ruleBases.put(ruleAgentProperties, ruleBase);
+
+				message = executeStatefulRules(ruleBase, dispose, message,
+						objectList);
+
+				long procTime = System.nanoTime() - startTime;
+				if (rulesCounter != null) {
+					rulesCounter.update(procTime, ruleAgentProperties,
+							JBRulesCounter.RULES_SUCCEED);
+				}
+			}
+
+			return message;
+
+		} catch (IOException ioe) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, ruleAgentProperties,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException(
+					"Could not read the ruleAgentProperties. "
+							+ ioe.getMessage(), ioe);
+		} catch (RuleServiceException ree) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, ruleAgentProperties,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not parse the rules. "
+					+ ree.getMessage(), ree);
+		} catch (Exception e) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, ruleAgentProperties,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException(
+					"RuleAgent could not get the RuleBase. " + e.getMessage(),
+					e);
+		}
+
+	}
+
+	/**
+	 * Continue executing rules where the working memory already exists.
+	 * 
+	 * @param rules -
+	 *            String reference to a file, either the drl file, the decision table,
+	 *            or the ruleAgentProperties. This is used to find the ruleBase.
+	 * @param dispose -
+	 *            if set to true, working memory will be disposed after the rules are fired
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message continueStatefulRulesExecution(String rules,
+			boolean dispose, Message message, List<Object> objectList)
+			throws RuleServiceException {
+		long startTime = System.nanoTime();
+		try {
+			final Map<String, RuleBase> ruleBases = lifecycleRuleBases
+					.getLifecycleResource();
+
+			RuleBase ruleBase = ruleBases.get(rules);
+			StatefulSession[] workingMemories = ruleBase.getStatefulSessions();
+			// there should only be one created from this ruleBase?
+			StatefulSession workingMemory = workingMemories[0];
+			logger
+					.log(Level.DEBUG, "Executing rules with RuleBase="
+							+ ruleBase);
+
+			workingMemory.setGlobal("message", message);
+
+			if (objectList != null) {
+				for (Object object : objectList) {
+					workingMemory.insert(object);
+				}
+			}
+
+			// workingMemory.insert(message);
+			logger.log(Level.DEBUG, "Fire the JBossRules Engine");
+			workingMemory.fireAllRules();
+
+			logger.log(Level.DEBUG, "Updated message: " + message);
+
+			if (dispose) {
+				workingMemory.dispose();
+			}
+
+			long procTime = System.nanoTime() - startTime;
+			if (rulesCounter != null) {
+				rulesCounter.update(procTime, rules,
+						JBRulesCounter.RULES_SUCCEED);
+			}
+
+			return message;
+
+		} catch (Exception e) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, rules,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException(
+					"Could not continue rule execution. " + e.getMessage(), e);
+		}
+	}
+
+	/**
+	 * Determine if file based rules need reloading and return the rulebase
+	 * 
+	 * @param ruleSet -
+	 *            String reference to a file which contains a ruleSet.
+	 * @param dsl -
+	 *            String reference to a file which contains a custom rule language
+	 *            definition
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading the
+	 *            ruleSet.
+	 * 
+	 * @return Message with updated objects.
+	 */
+	protected RuleBase getRuleBaseForFileBasedRules(String ruleSet, String dsl,
+			boolean ruleReload) throws RuleServiceException {
+		long startTime = System.nanoTime();
+		try {
+			DroolsRuleBaseHelper rbHelper = new DroolsRuleBaseHelper();
+
+			String newRuleSet = null;
+			boolean isRulesChanged = false;
+
+			final Map<String, String> ruleSets = lifecycleRuleSets
+					.getLifecycleResource();
+			if (ruleReload) {
+				String currentRuleSet = ruleSets.get(ruleSet);
+				newRuleSet = rbHelper.getRulesAsString(ruleSet, dsl);
+				if (currentRuleSet == null
+						|| !currentRuleSet.equals(newRuleSet)) {
+					isRulesChanged = true;
+				}
+
+			}
+			final Map<String, RuleBase> ruleBases = lifecycleRuleBases
+					.getLifecycleResource();
+			RuleBase ruleBase = ruleBases.get(ruleSet);
+			if (ruleBase == null || isRulesChanged) {
+				logger.log(Level.DEBUG, "Reading ruleSet from file=" + ruleSet);
+				ruleBase = rbHelper.createRuleBaseFromRuleFiles(ruleSet, dsl);
+				if (ruleBase != null)
+					ruleBases.put(ruleSet, ruleBase);
+				if (newRuleSet == null) {
+					newRuleSet = rbHelper.getRulesAsString(ruleSet, dsl);
+				}
+				if (ruleSet != null)
+					ruleSets.put(ruleSet, newRuleSet);
+			}
+
+			// this should really be a RULES_COMPILED status, and processing time should be compilationTime
+			// long procTime = System.nanoTime() - startTime;
+			// if (rulesCounter != null) {
+			// 	rulesCounter.update(procTime, ruleSet, JBRulesCounter.RULES_SUCCEED);
+			// }
+
+			return ruleBase;
+
+		} catch (final LifecycleResourceException lre) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, ruleSet,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not load lifecycle data. "
+					+ lre.getMessage(), lre);
+		} catch (IOException ioe) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, ruleSet,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not read the rules. "
+					+ ioe.getMessage(), ioe);
+		} catch (DroolsParserException dpe) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, ruleSet,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not parse the rules. "
+					+ dpe.getMessage(), dpe);
+		} catch (RuleServiceException ree) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, ruleSet,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not parse the rules. "
+					+ ree.getMessage(), ree);
+		}
+
+	}
+
+	/**
+	 * Determine if decision table need reloading and return the rulebase
+	 * 
+	 * @param ruleSet -
+	 *            String reference to a file which contains a ruleSet.
+	 * @param dsl -
+	 *            String reference to a file which contains a custom rule language
+	 *            definition
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading the
+	 *            ruleSet.
+	 * 
+	 * @return Message with updated objects.
+	 */
+	protected RuleBase getRuleBaseForDecisionTable(String decisionTable,
+			boolean ruleReload) throws RuleServiceException {
+		long startTime = System.nanoTime();
+		try {
+			DroolsRuleBaseHelper rbHelper = new DroolsRuleBaseHelper();
+			RuleBase ruleBase;
+			if (ruleReload) {
+				String drl = rbHelper.getSpreadsheetRules(decisionTable);
+				ruleBase = getRuleBaseForFileBasedRules(drl, null, ruleReload);
+			} else {
+				ruleBase = rbHelper
+						.createRuleBaseFromDecisionTable(decisionTable);
+			}
+			// this should really be a RULES_COMPILED status, and processing time should be compilationTime
+			// long procTime = System.nanoTime() - startTime;
+			// if (rulesCounter != null) {
+			// 	rulesCounter.update(procTime, ruleSet, JBRulesCounter.RULES_SUCCEED);
+			// }
+			return ruleBase;
+
+		} catch (IOException ioe) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, decisionTable,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not read the rules. "
+					+ ioe.getMessage(), ioe);
+		} catch (DroolsParserException dpe) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, decisionTable,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not parse the rules. "
+					+ dpe.getMessage(), dpe);
+		} catch (RuleServiceException ree) {
+			if (rulesCounter != null) {
+				long procTime = System.nanoTime() - startTime;
+				rulesCounter.update(procTime, decisionTable,
+						JBRulesCounter.RULES_FAILED);
+			}
+			throw new RuleServiceException("Could not parse the rules. "
+					+ ree.getMessage(), ree);
+		}
+	}
+
+	/**
+	 * Execute rules using using the Stateless API
+	 * 
+	 * @param rulebase -
+	 *            the rulebase to use
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList -
+	 *            a list with additional objects (typically pulled from the message)
+	 *            to be inserted into working memory
+	 * 
+	 * @return Message with updated objects.
+	 */
+	@SuppressWarnings("unchecked")
+	protected Message executeStatelessRules(RuleBase ruleBase, Message message,
+			List<Object> objectList) {
+		StatelessSession workingMemory = ruleBase.newStatelessSession();
+		logger.log(Level.DEBUG, "Executing rules with RuleBase=" + ruleBase);
+
+		List<Object> facts = new ArrayList(objectList);
+		workingMemory.setGlobal("message", message);
+		logger.log(Level.DEBUG, "Fire the Drools Rules Engine");
+		workingMemory.execute(facts);
+
+		return message;
+	}
+
+	/**
+	 * Execute rules using using the Stateful API
+	 * 
+	 * @param rulebase -
+	 *            the rulebase to use
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList -
+	 *            a list with additional objects (typically pulled from the message)
+	 *            to be inserted into working memory
+	 * 
+	 * @return Message with updated objects.
+	 */
+	protected Message executeStatefulRules(RuleBase ruleBase, boolean dispose,
+			Message message, List<Object> objectList) {
+
+		StatefulSession workingMemory = ruleBase.newStatefulSession();
+		logger.log(Level.DEBUG, "Executing rules with RuleBase=" + ruleBase);
+
+		workingMemory.setGlobal("message", message);
+
+		if (objectList != null) {
+			for (Object object : objectList) {
+				workingMemory.insert(object);
+			}
+		}
+
+		logger.log(Level.DEBUG, "Fire the JBossRules Engine");
+		workingMemory.fireAllRules();
+
+		logger.log(Level.DEBUG, "Updated message: " + message);
+
+		if (dispose) {
+			workingMemory.dispose();
+		}
+		return message;
+	}
+
+	public void setConfigTree(ConfigTree configTree) {
+		rulesCounter = new JBRulesCounter(configTree);
+		rulesCounter.registerMBean();
+	}
+
+	/**
+	 * The lifecycle resource factory for rule sets.
+	 * 
+	 * @author kevin
+	 */
+	public static class LifecycleRuleBaseFactory implements
+			LifecycleResourceFactory<Map<String, RuleBase>> {
+		/**
+		 * Create a resource object which will be associated with the
+		 * specified lifecycle identity.
+		 * 
+		 * @param lifecycleIdentity
+		 *            The associated lifecycle identity.
+		 * @return The lifecycle resource
+		 * @throws LifecycleResourceException
+		 *             for errors during construction.
+		 */
+		public Map<String, RuleBase> createLifecycleResource(
+				final String lifecycleIdentity)
+				throws LifecycleResourceException {
+			return new ConcurrentHashMap<String, RuleBase>();
+		}
+
+		/**
+		 * Destroy a resource object which is associated with the specified
+		 * lifecycle identity.
+		 * 
+		 * @param resource
+		 *            The lifecycle resource.
+		 * @param lifecycleIdentity
+		 *            The associated lifecycle identity.
+		 * @return The lifecycle resource.
+		 * @throws LifecycleResourceException
+		 *             for errors during destroy.
+		 */
+		public void destroyLifecycleResource(
+				final Map<String, RuleBase> resource,
+				final String lifecycleIdentity)
+				throws LifecycleResourceException {
+		}
+	}
+
+	/**
+	 * The lifecycle resource factory for rule sets.
+	 * 
+	 * @author kevin
+	 */
+	public static class LifecycleRuleSetFactory implements
+			LifecycleResourceFactory<Map<String, String>> {
+		/**
+		 * Create a resource object which will be associated with the
+		 * specified lifecycle identity.
+		 * 
+		 * @param lifecycleIdentity
+		 *            The associated lifecycle identity.
+		 * @return The lifecycle resource
+		 * @throws LifecycleResourceException
+		 *             for errors during construction.
+		 */
+		public Map<String, String> createLifecycleResource(
+				final String lifecycleIdentity)
+				throws LifecycleResourceException {
+			return new ConcurrentHashMap<String, String>();
+		}
+
+		/**
+		 * Destroy a resource object which is associated with the specified
+		 * lifecycle identity.
+		 * 
+		 * @param resource
+		 *            The lifecycle resource.
+		 * @param lifecycleIdentity
+		 *            The associated lifecycle identity.
+		 * @return The lifecycle resource.
+		 * @throws LifecycleResourceException
+		 *             for errors during destroy.
+		 */
+		public void destroyLifecycleResource(
+				final Map<String, String> resource,
+				final String lifecycleIdentity)
+				throws LifecycleResourceException {
+		}
+	}
+}

Added: labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceException.java
===================================================================
--- labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceException.java	                        (rev 0)
+++ labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceException.java	2008-01-03 00:52:23 UTC (rev 17507)
@@ -0,0 +1,46 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.internal.soa.esb.services.rules;
+
+/**
+ * @author jdelong at redhat.com
+ * 
+ */
+public class RuleServiceException extends Exception {
+	private static final long serialVersionUID = 1L;
+
+	public RuleServiceException() {
+		super();
+	}
+
+	public RuleServiceException(String msg) {
+		super(msg);
+	}
+
+	public RuleServiceException(Throwable cause) {
+		super(cause);
+	}
+
+	public RuleServiceException(String msg, Throwable cause) {
+		super(msg, cause);
+	}
+}

Added: labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceFactory.java
===================================================================
--- labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceFactory.java	                        (rev 0)
+++ labs/jbossesb/workspace/jdelong/ruleservice/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceFactory.java	2008-01-03 00:52:23 UTC (rev 17507)
@@ -0,0 +1,62 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.internal.soa.esb.services.rules;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.jboss.soa.esb.services.rules.RuleService;
+import org.jboss.soa.esb.util.ClassUtil;
+/**
+ * Returns an instance of the RuleService.
+ *
+ * @author jdelong at redhat.com
+ *
+ */
+public class RuleServiceFactory {
+	private static Logger logger = Logger.getLogger(RuleServiceFactory.class);
+
+	/**
+	 * This factory returns a ruleService
+	 * 
+	 * @author jdelong at redhat.com
+	 * 
+	 */
+	public static RuleService getRuleService(String className)
+			throws RuleServiceException {
+		RuleService rs = null;
+		logger.log(Level.DEBUG, "Going to load " + className);
+		try {
+			// instruct class loader to load the RuleService Implementation
+			Class rsClass = ClassUtil.forName(className,
+					RuleServiceFactory.class);
+			// Try to get an instance of the RS
+			rs = (RuleService) rsClass.newInstance();
+		} catch (ClassNotFoundException cnfex) {
+			throw new RuleServiceException("RuleService Implementation="
+					+ className + " not found", cnfex);
+		} catch (Exception e) {
+			throw new RuleServiceException(className + " invocation problem. "
+					+ e.getLocalizedMessage(), e);
+		}
+		return rs;
+	}
+}




More information about the jboss-svn-commits mailing list