Business Rules Management System (BRMS)
There is always the need to update your billing system to reflect your real-world business rules. In many cases, this will lead to ever-increasing complexity for the billing system. For example, it is very common that an item needs more than just a simple flat price. Many factors might need to be considered to determine that price, such as a volume discount, a limited-time promotion, or pricing based on the location of the customer. The possible options are endless.
Another area of a billing system that requires great flexibility is the relationship among items. If you could clearly establish 'commands' to how items relate to each other, then you could implement business rules such as: “if you buy 10 books, you get a free calendar,” or “bundle A includes a book, a calendar, and a poster.”
Those are just a few examples, they are only scratching the surface of what it could be a source of great complexity in a billing system. How can we possibly foresee all the factors and scenarios that the system needs to be flexible, so you can implement your business rules? Rather than trying to implement the flexibility directly into jBilling's core (and reinventing the wheel in the process), we integrated with a Business Rules Management System (BRMS). The following is a simple definition of BRMS, taken mostly from Wikipedia:
BRMS maintains rules that are executed in a production rule system but also maintained in a repository with a user interface suitable for business users to create, read, update and delete them. The main benefits of a BRMS are:
- Reduced or removed reliance on IT departments for changes in live systems. This means that to change a business rule, you don't need to change any code. It is all done through a GUI.
- Increased control over implemented business logic, for compliance and better business management.
Just like with enterprise billing systems, not long ago, acquiring a BRMS was an expensive proposition. The field was dominated by a handful of closed source providers with high-cost commercial licenses. There is now a very good open source alternative: Drools (also known as JBoss Rules), which includes a rule engine, web-based BRMS, development tools among other products.
Starting with version 1.1.0, jBilling includes full integration with Drools. You can configure jBilling to use an 'external rule' to determine, for example, the price of an item. This, added to brand new modules such as the Mediation module, takes jBilling to a whole new category of enterprise billing systems whose flexibility and power meets complex requirements such as those from the telecommunications industry.
This guide is an overview of how to implement rules and use a BRMS with jBilling. For a detailed documentation, read the jBilling Extension Guide.
Rules in Action
Without any more preambles, let's take a look to what can be done with rules. We will test the following requirements:
- A bundle to easily sell a group of items as a package.
- Taxation based on the customer's country.
- A 'plan' that includes a number of units for a period of time.
- Special pricing on some items to some customers.
After installing jBilling, you will be able to login to the example company 'Trend' with the user name 'admin', password '123qwe' and company ID. Make sure you have also followed the Getting Started guide that introduces you to the basic jBilling concepts, including items, orders, and invoices.
Trend, in its quest for a larger market share, has come up with a new offering. Now you can buy a monthly plan that includes 1000 clicks to your front page ad. Also part of the package is a special price for the monthly maintenance fee. So the bundle includes two items: the 1000 clicks (item 17) and the maintenance fee (item 12). Take a look at these items by clicking on the menu option 'Items.' They really don't look any different than a standard item; the additional logic is in the BRMS.
Now create a new order for customer 12. In the screen where you add items to the order, add the item 'Start-Up Plan - 1000 monthly clicks.' The surprise is that, instead of only that item getting into the order, you will also have the item 'Account maintenance fee - Plan discount' as well.
Here we have some simple rules that say “when the item 17 is part of the order, include also item 12.”
Trend is now operating in both the US and Canada. When selling in Canada, it has to charge the 'GST' (goods and services tax) to all sales. In the previous example, we used customer 12, whose address is from the US. Now try creating an order to any of the other two customers (2 or 22). When you add any item, an additional item is added: 'GST 6%,' which is just a simple item that belongs to a tax category and has a percentage price.
This logic is managed by the BRMS as a rule that states, “when the country of the customer's address is Canada, add item 11.”
Plan with included units
The item that represents a 'click' to the front-page banner is item 16, “Click on front page banner – generic”. This represents a 'generic' click, without making assumptions if the click is included in a plan or its price. Trend's web site will only need to know about this item when sending the numbers of clicks to jBilling. The website shows the ad, and counts the clicks without any knowledge about plans, prices or any billing related information.
How the website is integrated with jBilling, how it actually submits the click information, is out of scope for this guide. It can be done in real-time through the jBilling client API, or by using the Mediation module for batch updates. To illustrate this example, let's just add the clicks manually directly into an order.
Click on Orders then Create. Select customer 12, it is the one subscribed to the plan we are testing. Click on 'Continue' to get to the items page. Now add 999 of the “Click on front page banner – generic” item. After you click on 'Add' you will notice something odd. By looking at the Summary box on the top right corner, you can see that there are 999 units of an item, but is not the 'generic' one any more. Instead, you have 999 of the “Click on front page banner - included in plan” item.
Now add 2 more units of the “Click on front page banner – generic” item. Instead of getting the unit count to 1001 (999 + 2), you are getting the units of the “Click on front page banner - included in plan” item taken to 1000, and one unit of the “Click on front page banner”. Noticed that the first item has a price of zero dollars, while the second item is actual 10 cents. If you keep adding more units of the generic item, they will all go as paid units. This means that the customer is actually paying the regular price for any purchase that goes above the units included in the plan.
Another way to see how this plan is implemented is that the generic click item gets its units 'converted' to either free units included in the plan, or paid units, or may be both. This order would need to be a 'one-time' order, included in a monthly billing cycle. This way, a new one-time order will be created every month to keep track of the monthly usage. The customer will also have a monthly order with the bundle items, representing the monthly subscription. A single invoice will be generated combining both the monthly charges and the one-time items.
Now, try again doing what we've done here, but this time select a different customer. When you add units of the generic click item, they are always converted to paid units. This is because the other two customers do not have an recurring order with the bundle items, in other words, you need to be subscribed to the 1000 clicks plan to get free clicks.
This might look like a difficult scenario to implement, but it is very easy with the combination of jBilling's core billing features and two simple rules rule. The rules are “when adding item 16, if the customer is subscribed to item 12, convert the item to item 13”, and “if the order has more than 1000 units of item 13, send the excess to item 14”. It is really as simple as that, adding business login to jBilling through the BRMS is expressed in pretty much plain English. Keep reading for details.
Trend has negotiated some special prices with some customer. The first one is with Penny Bright. She is paying half price for the maintenance fee (from 10 to 5 dollars), but in exchange, she will be paying 11 cents a click (rather than the standard 10 cents). Terry Wilson, on the other hand, is a good old customer so he is getting 9 cents a click. Everybody else will simply use the default price that the item has.
When creating an order for any of these two customers, you can see that the price for item 14 is not $0.10, but $0.09 for 'twilson' or $0.11 for pbright. The default item price is actually 0.10, as you can see if you edit item 14. Also, our other customer, gets the regular price.
In order to override the default price, we created a new set of rules in the BRMS system in the form of a decision table. Here we can list customers and items and assign prices for each combination.
Installing the BRMS
As mentioned above, we use Drools as BRMS for jBilling. The BRMS itself is a web application that is deployed as a single 'war' file. Starting with jBilling 2, this web application is included in the main binary package that you get when downloading jBilling. Simply put, when you get jBilling, you already get the Drools GUI pre-installed.
Once the Tomcat is up, point your browser to: http://localhost:8080/drools-guvnor
The BRMS login screen should appear. By default, the system is not secured. You can enter 'admin' as user name without any password to login. For production deployments, there are many security options, including using your jBilling authentication credentials to access the BRMS.
Because you are running both applications (jBilling and Drools) in the same application server, when one is running the other one is running too. To learn more about installing Drools BRMS visit the Drools documentation page: http://labs.jboss.com/drools/documentation.html
jBilling's example packages
The BRMS that come with jBilling also includes a few packages with example rules pre-installed. Login to the BRMS with the user 'admin'. Click on the '+' sign just beside the “Knowledge Bases” option on the left menu. You will see three packages: “
trend_item_management” and “
trend_pricing”. These packages already have the headers and other definitions needed to create rules for jBilling, and also the example rules that we described earlier.
Some of the examples are done using Drools specific language. These are 'technical rules' and are typically done by developers: you need to know some programming to put one together. Other rules are 'business rules', you can use a user friendly GUI to create them and take advantage of a very intuitive Domain Specific Language (DSL). These rules are easy to manage by business users without the help of developers.
Technical rules are only needed in a development stage, when identifying what types of scenarios you will need to tackle with rules. The next step is to update the DSL to allow business users to work on business rules without any typing. In the example jBilling packages, you can take a look to both technical and business rules, as well as sample DSL for each package.
Two Simple Examples
Before diving into the examples, let's briefly touch on the required jBilling configuration. jBilling by default—that is, just after a new company is created—will not use rules for pricing or item relationship management. You need to configure specific plug-ins that enable rule-based functionality.
These plug-ins typically start with the name 'Rules,' and for the example company 'Trend,' they are all pre-configured. You do not need to add or change any configuration, but if you are curious, click on 'System,' then on 'Plug-ins' to take a look at these rule-specific plug-ins.
Let's now get into the details of two concrete examples just to have a feel for how the process of creating a business rule in the BRMS system works.
Pricing: Special prices
Click on 'trend_pricing' and then on 'Business rule assets' to find the customer pricing decision table. Double click on it to open the rule.
Pricing rules are used by jBilling when the price of an item is needed. The system will verify if there are any pricing rules available to override the simple price you give an item from jBilling's item screen. Let's take a look to this rule.
This pricing rule applies to two items and two customers. As you can see, the decision table is quite self-explanatory. When both the user and the item values of a specific row match, then the prices of that item are set to a concrete value.
Let's go over each column. The first one is just a sequence number to give each row (which translates to one rule) a unique number. Then there is the description, which is just text to document what that row is suppose to do (Drools ignores the column).
Then you have the condition columns: The user name and the item ID. They both have to match to set a new price.
Something to note is that we are using the item ID, which is 14, but this is not something that is easy to remember. You'd need to go to jBilling and look at the ID of the item you want to set a price for. Drools offers a better alternative, which is to configure item IDs as enumerations for drop down lists.
You could just map the '14' to some text like 'Standard click' in a static way. This can be OK if your list of items doesn't change much and is not long. If not, you can also configure the BRMS to dynamically load the item descriptions directly from jBilling.
This decision table could have any number of columns to do more complex conditions. To add more columns and more logic, you don't need to type any code, you just need to do some extra set-up of conditions right from this GUI.
Using this type of embedded decision table is convenient and easy. Still, you might prefer to use a standard spread sheet like Microsoft Excel or Open Office. With some extra configuration you can easily import rules in spreadsheet format.
Let's move on to the consequence of this rule. If both the item ID and the user name conditions are met, then the price should be set to a new value. This is done again using just a column to make this easy to use for business users. This, as opposed to the previous two columns, is an 'action' colum. It does not get much more simple than 'Set price to.' There is another consequence included in the example packages, and it is to change the price by a percentage. This allows you to give a 10 percent discount on whatever the price of the item is, for example.
The BRMS offers you this GUI to simplify creating and editing rules. Eventually, all of the rules get translated to plain text behind the scenes. Out of curiosity, you might want to click on the button 'View Source' to see how this rule would look like if written as a technical rule:
#from row number: 1 rule "Row 1 customer pricing" dialect "mvel" when user : UserDTOEx( userName == "pbright" ) helper : PricingManager( itemId == "14" ) then manager.setPrice( 0.11 ); end ...
rule “Bundle” when $item : ItemDTOEx( id == 12) then order.addItem(17); end
Mediation is a new module introduced with the release of jBilling 1.1.0. Its main function is to take a list of events and transform them into order lines that can then be included in invoices. This is a feature-rich and extensive module that has its own documentation. Here, we will only go over the main features without getting into the details.
The typical example is the call detail records left by a telephony switch. Each row in these files represents a phone call: The record includes when the call was made, by whom, to what number, the call duration, etc. A mediation process would have to take place periodically (usually daily) to take all of those records and update the billing system so customers get charged for the calls they made.
A mediation process then takes records that were left with information related to the provision of a service so that the billing system can be updated. To apply the example to Trend, it could be that its website generates a file with records that log website activities, what ads where shown, clicks, etc.
The sources of events can range from files to database tables. You could have a mix of them, with several systems creating records that need processing, each with its own record format. For example, it is common for a cell phone operator to sell voice, data, and messaging.
The format of the records that need processing is determined in a simple XML file. Take a look at the files located in the 'resources/mediation' directory of your jBilling installation. This is a section includes the file that describes the format of the popular Asterisk telephony system:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE format SYSTEM "mediation.dtd" > <format> <field> <name>accountcode</name> <type>string</type> </field> <field> <name>src</name> <type>string</type> </field> <field> <name>dst</name> <type>string</type> </field>
In these lines, there are three fields described, with only the data type being specified. jBilling supports formats where the fields are separated by a character (like asterisk with commas), and those with fixed positions (Dial Away is an example of those). You need to use a plug-in to tell jBilling what type of file has to be processed, its location, etc.
There are two things that the mediation process needs to do for each record. One is to determine which user that relates to the record; for the telephony example it would be the user that has made the phone call. The other is to update an order with the correct item for the given record. In other words, for a record that represents a phone call, we need to know who made the call, and which item represents that call, in jBilling.
Just like pricing and item relationships, this is done using rules and the BRMS to manage those rules. Each field coming from the file being processed is made available to the rules engine as a 'PricingField' object. The best part is that all of these fields are also available to the Pricing rules package to rate the event (more on this in the next section).
The user that owns the event can be determined in three ways: the user ID, the user name, or a custom field. Ideally, you will have the user name or ID coming as a field in your records. This is an example from the asterisk format:
when $field : PricingField( name == "userfield") then mediationManager.setUserFromUsername($field.getStrValue());
Here we are taking the value of the field 'userfield' as the jBilling user name.
jBilling now includes the concept of a 'current order.' This is a one-time order that carries the activity of a user for the current billing period. For a phone company, this current order would carry all the charges that are on top of the recurring plan. When the billing process takes place, the current order is included in the new invoice, and a new one-time order (empty) gets to be the current order.
You do not need to worry about finding the current order, but you need to determine the item that will be added to the order and the quantity. This is an example from the asterisk format:
when $field : PricingField( name == "duration") then mediationManager.addLine(1, $field.getIntValue());
Here we are always adding the same item (1), which could be a perfectly workable option. This item could represent a 'generic phone call' item just like the 'generic click' item in the previous examples. Then the quantity is taken from the 'duration' field which, in this case, is the duration of the phone call in seconds.
This only scratches the surface of this package. You can 'normalize' the record as well, manipulating and formating data with some rules so that other rules have a consistent input. There are advanced options as well, where many records are grouped together to be processed as a single unit, or the opposite, where one record translates into many charges.
Rating, plans, and bundles
A typical expectation from a Mediation process is to rate each event. Rating synonymous with assigning a price. In jBilling, when the mediation process takes place, rating is not really done; it is built-in with the system. However, when rating a mediation event—unlike rating a simple purchase of an item—there are many more factors to consider.
To continue with the telephony example, the rating will need to consider the time of the day, day of the week, phone number called, location where the call took place, and many others. All of these variables are provided to you by your telephony system in the form of fields in the CDR file. So all of these variables are also available to the Pricing package. This means that you can use any of the CDR fields described in the format XML file in your pricing rules by using the 'PricingField' object. This object is present in both the Mediation and Pricing rules packages.
In fact, all three rule-based packages, Mediation, Pricing, and Item Relationship, play a role to achieve the level of flexibility that a complex billing requires. Let's walk through the processing of a phone call event for a customer that is making an evening call, which is included in her 'unlimited evening calls' plan:
- The mediation process determines who the user is based on the source phone number.
- The mediation process adds an item called 'evening phone call' to the current order for the number of minutes the phone call lasted. The start and end time of the phone call are present as PricingFields.
- The item management package switches the item to be 'free evening call included in plan' which has a zero price.
In this example, the Pricing package did not even have to participate. If the call had been a long distance call, then it would have to determine the price of the call considering the origin and destination of the call.