Stocker la configuration

MRules fournit nativement deux moyens de fournir la configuration au moteur de règles :

  • Lecture d’un fichier (par un chemin absolu ou via le CLASSPATH).
  • Fournir directement le contenu XML. Cette deuxième option est plus orientée tests.

Il est probable que l’application utilisatrice soit conçue pour stocker la configuration par un autre moyen, par exemple en base de données. Ceci est bien entendu possible et facilité par les utilitaires fournis. La récupération en base de données de la configuration est encapsulée par une implémentation de IRuleEngineConfigHolder. Une implémentation abstraite AbstractRuleEngineConfigHolder effectuant des opérations génériques est fournie, il suffit de l’étendre avec sa propre implémentation.

On considère que la configuration du moteur de règles est stockée dans une table de la base de données, contenant trois champs :

  • Un code unique
  • Une date de dernière modification
  • Le XML à proprement parler

La classe MyDatabaseXmlConfigHolder devra surcharger / implémenter 3 méthodes :

  • init : initialisation du holder avec le paramètre « MyDatabaseXmlConfigHolder.code » contenant le code.
  • getConfigHash : devant retourner une chaîne de caractère permettant d’identifier les changement dans la configuration. Ici la date de dernière modification est idéale.
  • build : construction ou récupération de l’instance du moteur.

Exemple d’implémentation, redirigeant les appels base de données vers une classe DBService :

package com.massa.mrules.demos.site;

import java.io.StringReader;
import java.util.Map;

import com.massa.mrules.MRulesMessages;
import com.massa.mrules.builder.AbstractRuleEngineConfigHolder;
import com.massa.mrules.exception.MConfigurationException;
import com.massa.mrules.factory.xml.IRuleExecutionSetXMLFactory;
import com.massa.mrules.factory.xml.XMLMConfigurationException;
import com.massa.mrules.set.IMruleExecutionSet;
import com.massa.util.MessageInfo;
import com.massa.util.StringUtils;

/**
 * Example Config holder for retrieving configuration XML from database.
 * The table storing the XML is supposed to have (at least) these fields:
 *  - A code (unique identifier)
 *  - A last updated date
 *  - The XML content
 *
 *  The configholder must be provided one parameter: the target configuration code.
 */
public class MyDatabaseXmlConfigHolder extends AbstractRuleEngineConfigHolder {

	private String code;

	public MyDatabaseXmlConfigHolder() {
		super();
	}

	/**
	 * Initializes the config holder with the code parameter.
	 */
	@Override
	public void init(final Map<String, String> parameters) throws MConfigurationException {
		super.init(parameters);
		this.code = parameters.get("MyDatabaseXmlConfigHolder.code");
		if (StringUtils.isEmpty(this.code)) {
			throw new MConfigurationException(new MessageInfo(
					MRulesMessages.MRE_NULL_PARAMETER, "MyDatabaseXmlConfigHolder.code"));
		}
	}

	/**
	 * Returns the last updated date from DB.
	 */
	public String getConfigHash() throws XMLMConfigurationException {
		return Long.toString(DBService.getLastUpdateDate(this.code).getTime());
	}

	/**
	 * Builds or retrieves the rule set.
	 */
	public IMruleExecutionSet build() throws MConfigurationException {
		final String xmlContent = DBService.getXmlContent(this.code);
		final IRuleExecutionSetXMLFactory factory = (IRuleExecutionSetXMLFactory) this.getFactory();
		return factory.read(new StringReader(xmlContent));
	}
}

Ensuite, la récupération de l’instance du moteur se fait de façon standard, par exemple par injection :

package com.massa.mrules.demos.site;

import javax.inject.Inject;

import com.massa.mrules.inject.InjectProperty;
import com.massa.mrules.inject.MRulesInject;
import com.massa.mrules.set.IMruleExecutionSet;

/**
 * Building new Rule Enginefro; DB or retrieving it if already existing.
 */
public class InjectBuiltEngineFromDb {
    @Inject
    @MRulesInject(
        uri = "MyDbSessionURI",
        configHolderImpl = "com.massa.mrules.demos.site.MyDatabaseXmlConfigHolder",
        factoryImpl = "com.massa.mrules.factory.xml.RichXMLFactory",
        //allows to define properties to provide to the Rule Engine Builder
        //which are not natively recognized.
        properties = {
        		@InjectProperty(
        			property = "MyDatabaseXmlConfigHolder.code",
        			value = "MY_CODE"
        		)
        }
    )
    private IMruleExecutionSet set;

    //...
}