Package org.jboss.internal.soa.esb.services.rules

Source Code of org.jboss.internal.soa.esb.services.rules.RuleServiceCallHelper

/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* 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 static org.jboss.soa.esb.listeners.ListenerTagNames.RULE_RELOAD_TAG;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.CONTINUE;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.DECISION_TABLE;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.DISPOSE;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.IMPL_CLASS;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.RULE_AGENT_PROPERTIES;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.RULE_AUDIT_FILE;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.RULE_AUDIT_INTERVAL;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.RULE_AUDIT_TYPE;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.RULE_CLOCK_TYPE;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.RULE_EVENT_PROCESSING_TYPE;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.RULE_FIRE_METHOD;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.RULE_MAX_THREADS;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.RULE_MULTITHREAD_EVALUATION;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.STATEFUL;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.StringValue.FIRE_ALL_RULES;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.StringValue.FIRE_UNTIL_HALT;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.drools.runtime.Channel;
import org.jboss.soa.esb.Configurable;
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.common.Configuration;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.listeners.ListenerTagNames;
import org.jboss.soa.esb.message.Message;
import org.jboss.soa.esb.services.rules.RuleInfo;
import org.jboss.soa.esb.services.rules.RuleService;
import org.jboss.soa.esb.services.rules.ServiceChannel;
import org.jboss.soa.esb.services.rules.StatefulRuleInfo;
import org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.StringValue;
import org.jboss.soa.esb.util.ClassUtil;

/**
* RuleServiceCallHelper is a class for calling
* methods on a {@link RuleService} implementation.
* </p>
*
* @author <a href="mailto:dbevenius@redhat.com">Daniel Bevenius</a>
*
*/
public class RuleServiceCallHelper
{
    private static Logger logger = Logger.getLogger(RuleServiceCallHelper.class);
   
    /**
     * The default continue state expected.
     */
    private static final boolean DEFAULT_CONTINUE_STATE;
   
    /**
     * The {@link RuleService} implementation to use.
     */
    private RuleService ruleService;
   
    /**
     * The rule set.
     */
    private String ruleSet;
   
    /**
     * The optional rule language. (DSL)
     */
    private String ruleLanguage;
   
    /**
     * True if a ruleSet is being used.
     */
    private boolean useRuleSet;

    /**
     * The decision table to be use, if configured.
     */
    private String decisionTable;
    private boolean useDecisionTable;

    /**
     * The rule agent to be use, if configured.
     */
    private String ruleAgent;
    private boolean useRuleAgent;
   
    /**
     * Should this be a stateful rules execution.
     */
    private boolean stateful;
   
    /**
     * Controll the reloading of rules.
     */
    private boolean ruleReload;
   
    // audit parameters
    private String auditType;
    private String auditFile;
    private Integer auditInterval;
   
    // clock and event processing parameters
    private String clockType;
    private String eventProcessingType;
    private Boolean multithreadEvaluation;
    private Integer maxThreads;
   
    // channels (exit points)
    private Map<String,Channel> channels;
   
    // rule fire method
    private String ruleFireMethod;

  public RuleServiceCallHelper(final ConfigTree config) throws ConfigurationException
  {
        final String ruleServiceImpl = config.getAttribute(IMPL_CLASS.getName(), DroolsRuleService.class.getName());
        try
        {
            ruleService = RuleServiceFactory.getRuleService( ruleServiceImpl );
            ruleService.setConfigTree( config );
        }
        catch (RuleServiceException e)
        {
            throw new ConfigurationException("Could not create RuleService", e);
        }
       
        ruleSet = config.getAttribute(ListenerTagNames.RULE_SET_TAG);
        ruleLanguage = config.getAttribute(ListenerTagNames.RULE_LANGUAGE_TAG);
       
        String ruleReloadStr = config.getAttribute(ListenerTagNames.RULE_RELOAD_TAG);
        if (ruleReloadStr != null && "true".equals(ruleReloadStr))
        {
            ruleReload = true;
        }
       
        auditType = config.getAttribute( RULE_AUDIT_TYPE.getName() );
        auditFile = config.getAttribute( RULE_AUDIT_FILE.getName() );
        String rai = config.getAttribute( RULE_AUDIT_INTERVAL.getName() );
        auditInterval = (rai != null) ? Integer.valueOf(rai) : null;
       
        clockType = config.getAttribute( RULE_CLOCK_TYPE.getName() );
        eventProcessingType = config.getAttribute( RULE_EVENT_PROCESSING_TYPE.getName() );
        String rme = config.getAttribute( RULE_MULTITHREAD_EVALUATION.getName() );
        multithreadEvaluation = (rme != null) ? Boolean.valueOf(rme) : null;
        String rmt = config.getAttribute( RULE_MAX_THREADS.getName() );
        maxThreads = (rmt != null) ? Integer.valueOf(rmt) : null;
       
        channels = getChannels(config);
       
        ruleFireMethod = config.getAttribute( RULE_FIRE_METHOD.getName() );
       
        useRuleSet = ruleSet != null;
        if (ruleSet == null)
        {
            // Extract the decision table from the configuration(if configured).
            decisionTable = config.getAttribute( DECISION_TABLE.getName() );
            useDecisionTable = decisionTable != null;
           
            if (useDecisionTable == false)
            {
                // Extract the ruleAgent from the configuration(if configured).
                ruleAgent = config.getAttribute( RULE_AGENT_PROPERTIES.getName() );
                useRuleAgent = true;
       
                if(logger.isDebugEnabled())
                {
                    if (ruleAgent != null && ruleReload)
                    {
                        logger.debug("'" + RULE_RELOAD_TAG + "' is specified on the same configuration as a Rule Agent configuration is specified.  Ignoring the '" + RULE_RELOAD_TAG + "' configuration.");
                    }
                }
            }
        }
       
        stateful = Boolean.valueOf(config.getAttribute(STATEFUL.getName())).booleanValue();
  }
   
    @SuppressWarnings("unchecked")
  static Map<String,Channel> getChannels(final ConfigTree config) throws ConfigurationException
    {
      Map<String,List<Channel>> channel_list_map = new HashMap<String,List<Channel>>();
      ConfigTree[] send_to_cfgs = config.getChildren("send-to");
      for (ConfigTree send_to_cfg : send_to_cfgs)
      {
        String channel_name = send_to_cfg.getRequiredAttribute("channel-name");
        List<Channel> channel_list = channel_list_map.get(channel_name);
        if (channel_list == null)
        {
          channel_list = new ArrayList<Channel>();
          channel_list_map.put(channel_name, channel_list);
        }
        String channel_class_name = send_to_cfg.getAttribute("channel-class", ServiceChannel.class.getName());
        Channel channel;
        try
        {
          Class<Channel> channel_class = (Class<Channel>)ClassUtil.forName(channel_class_name, RuleServiceCallHelper.class);
          channel = channel_class.newInstance();
          if (channel instanceof Configurable)
          {
            ((Configurable)channel).setConfiguration(send_to_cfg);
          }
          channel_list.add(channel);
        }
        catch (ClassNotFoundException cnfe)
        {
          throw new ConfigurationException("could not find channel-class: " + channel_class_name, cnfe);
        }
        catch (Exception nsme)
        {
          throw new ConfigurationException("problem instantiating channel-class: " + channel_class_name, nsme);
        }
      }
      Map<String,Channel> channel_map = new HashMap<String,Channel>();
      for (Entry<String,List<Channel>> entry : channel_list_map.entrySet())
      {
        String channel_name = entry.getKey();
        final List<Channel> channel_list = entry.getValue();
        int channel_list_size = channel_list.size();
        if (channel_list_size == 1)
        {
          channel_map.put(channel_name, channel_list.get(0));
        }
        else if (channel_list_size > 1)
        {
          channel_map.put(channel_name, new Channel() {
            public void send(Object object) {
              for (Channel channel : channel_list) {
                channel.send(object);
              }
            }
          });
        }
      }
      return channel_map;
    }
   
    public Message executeRulesService(final RuleInfo ruleInfo, final Message message) throws RuleServiceException
    {
        if (isStateful())
        {
            return executeStateful(ruleInfo, message);
        }
        else
        {
            return executeStateless(ruleInfo, message);
        }
    }
   
    public Message executeStateless(final RuleInfo ruleInfo, final Message message) throws RuleServiceException
    {
        if (useRuleSet)
        {
            return ruleService.executeStatelessRules(ruleInfo, message);
        }
        else if (useDecisionTable)
        {
            return ruleService.executeStatelessRulesFromDecisionTable(ruleInfo, message);
        }
        else if (useRuleAgent)
        {
            return ruleService.executeStatelessRulesFromRuleAgent(ruleInfo, message);
        }
        else
        {
            throw new RuleServiceException( "One of '" + ListenerTagNames.RULE_SET_TAG + "', '" + DECISION_TABLE.getName() + "', or ' " + RULE_AGENT_PROPERTIES.getName() + "'must be specified as properties in jboss-esb.xml");
        }
       
    }
   
    public Message executeStateful(final RuleInfo ruleInfo, final Message message) throws RuleServiceException
    {
      // validates ruleFireMethod configuration
    isFireUntilHalt(ruleInfo);
     
        final boolean dispose = isDispose(message);
       
        // validates (explicitContinueState && (diposeProperty != null))
        final boolean explicitContinueState = isExplicitContinueState(message);
        final boolean continueState = explicitContinueState || isContinueStateOrDefault(message);
       
        final StatefulRuleInfo statefulRuleInfo = new StatefulRuleInfoImpl(ruleInfo, dispose, continueState);
       
        if (explicitContinueState)
        {
            return ruleService.continueStatefulRulesExecution(statefulRuleInfo, message);
        }
        else
        {
            if (useRuleSet)
            {
                return ruleService.executeStatefulRules(statefulRuleInfo, message);
            }
            else if (useDecisionTable)
            {
                return ruleService.executeStatefulRulesFromDecisionTable(statefulRuleInfo, message);
            }
            else if (useRuleAgent)
            {
                return ruleService.executeStatefulRulesFromRuleAgent(statefulRuleInfo, message);
            }
            else
            {
                throw new RuleServiceException( "One of '" + ListenerTagNames.RULE_SET_TAG + "', '" + DECISION_TABLE.getName() + "', or ' " + RULE_AGENT_PROPERTIES.getName() + "'must be specified as properties in jboss-esb.xml");
            }
        }
    }
   
    public String determineRuleSource()
    {
        if (useRuleSet)
        {
            return ruleSet;
        }
        else if (useDecisionTable)
        {
            return decisionTable;
        }
        else
        {
            return ruleAgent;
        }
    }
   
    public boolean isUseRuleSet()
    {
        return useRuleSet;
    }
   
    public boolean isUseDecisionTable()
    {
        return useDecisionTable;
    }
   
    public boolean isUseRuleAgent()
    {
        return useRuleAgent;
    }
   
    public boolean isStateful()
    {
        return stateful;
    }
   
    public String getRuleSet()
    {
        return ruleSet;
    }

    public String getRuleLanguage()
    {
        return ruleLanguage;
    }

    public String getDecisionTable()
    {
        return decisionTable;
    }

    public String getRuleAgent()
    {
        return ruleAgent;
    }

    public boolean isRuleReload()
    {
        return ruleReload;
    }
   
    public String getAuditType()
    {
      return auditType;
    }
   
    public String getAuditFile()
    {
      return auditFile;
    }
   
    public int getAuditInterval()
    {
      return auditInterval;
    }
   
    public String getClockType()
    {
      return clockType;
    }
   
    public String getEventProcessingType()
    {
      return eventProcessingType;
    }
   
    public Boolean getMultithreadEvaluation()
    {
      return multithreadEvaluation;
    }
   
    public Integer getMaxThreads()
    {
      return maxThreads;
    }
   
    public Map<String,Channel> getChannels()
    {
      return channels;
    }
   
    public String getRuleFireMethod()
    {
      return ruleFireMethod;
    }

    public RuleInfoBuilder getRuleInfoBuilder()
    {
        final RuleInfoBuilder builder = new RuleInfoBuilder(determineRuleSource());
        builder.dslSource(ruleLanguage);
        builder.reload(ruleReload);
        builder.auditType(auditType);
        builder.auditFile(auditFile);
        builder.auditInterval(auditInterval);
        builder.clockType(clockType);
        builder.eventProcessingType(eventProcessingType);
        builder.multithreadEvaluation(multithreadEvaluation);
        builder.maxThreads(maxThreads);
        builder.channels(channels);
        builder.ruleFireMethod(ruleFireMethod);
        return builder;
    }
   
  static boolean isFireUntilHalt(final RuleInfo ruleInfo) throws RuleServiceException
  {
    if (ruleInfo != null)
    {
      String ruleFireMethodConfig = ruleInfo.getRuleFireMethod();
      if (ruleFireMethodConfig != null)
      {
        StringValue ruleFireMethodValue = RULE_FIRE_METHOD.getStringValue(ruleFireMethodConfig);
        if (FIRE_UNTIL_HALT.equals(ruleFireMethodValue))
        {
          return true;
        }
        else if (!FIRE_ALL_RULES.equals(ruleFireMethodValue))
        {
          throw new RuleServiceException("unrecognized " + RULE_FIRE_METHOD.getName() + ": " + ruleFireMethodConfig);
        }
      }
    }
    return false;
  }
 
  private static boolean isDispose(final Message message)
  {
      Object disposeProperty = message.getProperties().getProperty(DISPOSE.getName());
      return (disposeProperty != null) && Boolean.parseBoolean(disposeProperty.toString());
  }
   
    private static boolean isExplicitContinueState(final Message message) throws RuleServiceException
    {
      final Object continueProperty = message.getProperties().getProperty(CONTINUE.getName());
      final boolean isExplicitContinueState = (continueProperty) != null ? Boolean.parseBoolean(continueProperty.toString()) : false;
      if (isExplicitContinueState)
      {
        final Object disposeProperty = message.getProperties().getProperty(DISPOSE.getName());
        if (disposeProperty == null)
        {
          throw new RuleServiceException(
            "The [" + DISPOSE.getName() + "] property must be specified when the [" +
            CONTINUE.getName() + "] property is specified as true. This is required as it is" +
            " important that the rules working memory be disposed or memory leaks can occur." );
        }
      }
      return isExplicitContinueState;
    }
   
    private static boolean isContinueStateOrDefault(final Message message) throws RuleServiceException
    {
        final Object continueProperty = message.getProperties().getProperty(CONTINUE.getName());
        if (continueProperty != null)
        {
          return Boolean.parseBoolean(continueProperty.toString());
        }
        else
        {
            return DEFAULT_CONTINUE_STATE;
        }
    }
   
    static
    {
        DEFAULT_CONTINUE_STATE = Boolean.parseBoolean(Configuration.getRulesContinueState());
    }
}
   
TOP

Related Classes of org.jboss.internal.soa.esb.services.rules.RuleServiceCallHelper

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.