[ Documentation Index ]

Extending WSO2 Business Rules Server (BRS)

This document explains extensibility points BRS provides.

Contents

Writing Adapters

There are two categories of adapters: fact adapters and result adapters.

Use Cases

Fact adapter can be used to populate facts from the incoming message in custom ways. A few use cases are shown bellow.

  1. JMS object message - If the facts are come as JMS object message, then, there is no way for standard POJO adapter to extract Java objects from the Object Message.
  2. JMS Map message - The use case is same as the JMS object message
  3. Custom POJO adapters - May be your own one or some adapter based on library such as XStream
  4. Some rule engine may support DOM as facts and therefore a DOM fact adapter may be useful.

Use cases for the result adapters can be derived form the above same use cases. For example, the results may be required to send using JMS object messages

Fact Adapter

Fact adapter is to convert a given object to a specific type. E.g.: POJO adapter converts an XML into a POJO fact. Fact adapter should implement Input Adaptable Interface

/**
 * Adapts the given object based on the resource description. Note here that the given 'tobeAdapted' is
 * data and only need to convert that into the correct target type.
 */
public interface InputAdaptable {

    /**
     * Converts the provided object into the object type defined in the resource description
     *
     * @param resourceDescription Input ResourceDescription
     * @param tobeAdapted         The final calculated value ,
     *                            only need to convert that into correct type
     * @return Converted object representing expected type
     */
    Object adaptInput(ResourceDescription resourceDescription,
                      Object tobeAdapted);
}

Result Adapter

Result Adapter is to process results from the rule execution and enrich the message with results. E.g.: POJO adapter covert POJOs into XML and enrich the message with those XML. Result Adapter should implement Output Adaptable Interface

/**
 * Adapts a result based on output description. Before call for adapt ,
 * it is recommended to explicitly checks for whether result can be adapted or not
 */

public interface OutputAdaptable {

    /**
     * Adapts the result according to the corresponding output description. The result of adaptation
     * is put into the context based on the information in the output description.
     *
     * @param description        Output ResourceDescription
     * @param result             Result from the engine
     * @param context            the context to be used for looking up resources
     * @param messageInterceptor a helper class to locate resources from given context
     * @return True if Successfully adapt
     */
    boolean adaptOutput(ResourceDescription description,
                        Object result,
                        Object context,
                        MessageInterceptor messageInterceptor);

    /**
     * Explicitly checks for whether result can be adapted or not
     *
     * @param description Output ResourceDescription
     * @param output      Result from the engine
     * @return True if it is possible to successfully adapt
     */
    boolean canAdaptOutput(ResourceDescription description,
                           Object output);

    /**
     * Adapts the result according to the corresponding output description.
     *
     * @param description information about target object
     * @param result      the object to be adapted
     * @return Adapted Object
     */
    public Object adaptOutput(ResourceDescription description, Object result);
}

Any Adapter to be an adapter it should implements ResourceAdapter interface

/**
 * Resources Adapter - This can be adapted input or output. It is needed to tell what can adapt
 * using OutputAdaptable, InputAdaptable , etc.
 */
public interface ResourceAdapter {

    /**
     * Type of  the resource that this adapter responsible for adapt. For an input, the type is the target type
     * for an output , it is a type of the source
     *
     * @return Resource type
     */
    String getType();
}

Adapters can be registered through rule-component .conf. Please refer configuration guide for more information

Adding New Rule Engines

New Rule engine can be added and there are two ways for doing it.

JSR 94

If the rule engine provides JSR 94 implementation, it can be registered as follows in the rule-component.conf

Our API

We are providing a simple API consisting with two interfaces: RuleBackendRuntime andRuleBackendRuntimeFactory. This is somewhat analog to what JSR 94 is doing. However, this is simple API and provides functions required for WSO2 BRS. This also enables to use native rule engine API that in turn allows doing more optimization, offer functionalities, and takes advantage of new functions offered by the rule engine, which are provided only through the native API. We have not control with JSR 94 API implementations. However, we have control over our API.

RuleBackendRuntime

/**
 * Encapsulates the rule service provider or the engine implements a rule engine. This adapts an
 * existing rule engine implementation.
 * <p/>
 * This class exposes functionality required to create a rule execution set, a session associated
 * with a rule execution set and  remove a registered execution set. Furthermore, this provide a
 * way to destroy underlying rule engine.
 */
public interface RuleBackendRuntime {

    /**
     * Registers a rule set. The rule set should be given in the RuleSetDescription as the rule source.
     * Within this method , an executable rule set is created and registered with the rule engine
     *
     * @param description information about the rule set
     * @return Registered URI of the rule set
     */
    public String addRuleSet(RuleSetDescription description);

    /**
     * Create a session based on the given SessionDescription. The session can be stateful or stateless
     *
     * @param sessionDescription information about the session to be created
     * @return a valid <code>Session</code> object, either stateful or stateless
     */
    public Session createSession(SessionDescription sessionDescription);

    /**
     * Removed a already registered rule set
     *
     * @param description information about the rule set to be removed
     */
    public void removeRuleSet(RuleSetDescription description);

    /**
     * Cleanup any resources used by the rule engine
     */
    public void destroy();
}

RuleBackendRuntimeFactory

/**
 * A factory for creating a RuleBackendRuntime. This should provide a properly initiated
 * RuleBackendRuntime instance. It is recommended to use this class as the only means for creating
 * RuleBackendRuntime instances
 */
public interface RuleBackendRuntimeFactory {
    /**
     * Returns a  properly initiated RuleBackendRuntime instance.
     *
     * @param properties  properties to be used when creating the underlying rule service provider
     * @param classLoader class loader to be used by the underlying rule service provider to load
     *                    facts and other required classes
     * @return properly initiated <code>RuleBackendRuntime</code>  instance if there are on exceptions.
     *         Otherwise, <code>LoggedRuntimeException/code> should be thrown.
     */
    public RuleBackendRuntime createRuleBackendRuntime(Map<String, PropertyDescription> properties,
                                                       ClassLoader classLoader);
}

Integrating with Other Systems

Please refer Developer Guide for knowing how to integrate the rules component with other systems.