BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Articles Lightweight External Business Rules

Lightweight External Business Rules

Key Takeaways

  • External rules simplify custom business logic for non-developer subject experts.
  • The Java lambda syntax is easier to read and write than large rules engines.
  • By combining Java lambda syntax with an external rules engine, subject experts can customize their application with low-code tools.

Complex enterprise applications usually come with varying Business logic. Such conditions and subsequent system actions, known as RULES, are ever varying and demand involvement of Domain-Specific Knowledge more than technology and programming. The rules, therefore, must reside outside the codebase and are to be authored by people with Core Domain expertise with little to no- technical /programming knowledge. A specific type of Software Tools, known as Rule Engines, cater to this context. Domain experts need not necessarily be active contributors to coding and technology, very much like brand-and-marketing teams who need not be aware of underlying technologies of the organization's portal and mobile application but be happy to author images, banners and other contents with little effort, with the ease of using one’s Instagram handle. Adobe aem is one of the content management systems that offers no-code / low-code content authoring. emerging technologies and cloud platforms have been constantly coming up with low-code and no-code solutions which have been widely embraced. This article presents a lightweight approach to externalize business actions into low-code tools, enabling contributions from people with respective domain expertise.

While we have many such Rule engines around, such as Drools (which is a feature-rich Business rule management system), easy rules, rule book, oracle rules SDK, Blaze (fico), IBM decision manager etc. enabling rule management declaratively with their respective rich features including version control are often very useful for lot of the applications. however, in certain lesser complex solutions, they often turn out to be overkill and remain underutilized. maintenance of an additional component becomes more of a liability than an asset.

In this article, we attempt to illustrate how inherent features of Java can be leveraged to externalize Rules in the simplest possible way, without narrowing down to any transitive dependency of additional frameworks. The approach is useful when technical rules (snippet written in java) needs to be externalized and can change frequently. The approach, therefore, holds equally worthy across any Java ecosystem, regardless of frameworks. Providing a simple POJO based declarative model for rules (which are java code snippets representing a predicate or an equivalent lambda expression)  that are loaded from an external source, say, for example, a file or a URL,  (an external source whose contents are in the Java lambda-style expressions or java code snippets) ranging from an on-premise database to a cloud resource ), it allows rules to be authored outside the application without even requiring application downtime. We can integrate it easily with Spring microservices and cloud configuration with and without Cloud bus. The approach provides encryption-at-rest to ensure safety (Confidentiality and Integrity) of business rules. Plus, apart from supporting Jasypt and Spring Config Ciphering, any custom security can be plugged-in to it.

Rule engine: The conventional way

The most conventional and ideal approach to cope up with frequent changes of Business Logic is a rule engine. A rule is generally  a set of IF-THEN conditions. 

RULE ≡ CONDITION + ACTION

Rule engines are Software Tools which, in short, provide us with the ability to set rules outside the source code. They allow rules to be set in various ways and by semi-technical/ non-programmer folks. They leverage Domain Specific Knowledge and offer GUI driven, intuitive authoring of Rules. Drools, DTRules, Oracle Policy Automation system, Easy-Rules are few examples of Rule Engines. 

Traditional rule engines that enable Domain-experts to author rule sets and behaviors outside the codebase, are highly useful for a complex and large business landscape. But  for smaller and less complex systems, they often turn out to be overkill and remain underutilised given the recurring cost of an on-premises or Cloud infrastructure they run on, License cost, etc. For a small team, adding any component requiring an additional skill set is a waste of its bandwidth. Some of the commercial rule engines have steep learning curves. In this article, we attempt to illustrate how we succeeded in maintaining rules outside source code to execute a medium scale system running on Java tech-stack like Spring Boot, making it easier for other users to customize these rules..   

This approach is suitable for a team that cannot afford a dedicated rule engine, its infrastructure, maintenance , recurring cost etc. and its domain experts have a foundation of Software or people within the team wear multiple hats.

This minimalist approach suits people who start a business - as we have always seen many big companies originated with small teams and budget and excellent talent and innovative ideas . Though size of team may not be perfectly conclusive , a team size of 10 or less with those given constraints gets the full benefit of this approach.

Teams having bigger size may benefit , as well , having cut down on dedicated rule engines  unless all cool and major features  of a commercially used one , are required.

Overview and novelty of the outcome 

Fig. 1 illustrates a higher-level, functional overview of the mechanism, while the steps listed below describe each of these components:

  

Figure 1

  1. The configuration stores rules, which are nothing but simple java methods or boolean expressions. To reduce verbosity of Java syntax, we accommodate Lamda and method references, too, thus providing an extra layer of abstraction over syntax of a Java method. 
  2. The configuration stores rules written by the domain expert. These are effectively statements, written like a lambda body that capture what the expert intends. For example to range an ESRB Mature video game as an age-appropriate product, the domain expert could write:
    customer -> customer.getAge()>=17
  3. The configuration can be  a file or stream of raw bytes or a URL and placed anywhere- providing plenty of wide range of options such as –
    • A file on local disk 
    • A database– both SQL and NoSQL
    • A remote Network location such as an HTTP URL, a raw TCP Socket, anything.
    • Cloud locations such as an AWS S3 bucket or Google drive location etc.
      The framework provides total abstraction to the source, its encoding, security and transport.  Any standard or proprietary CODEC can be used to store and retrieve the rules, and the same applies to the 2 major security paradigms - confidentiality and integrity. One can write one’s own Adapter in this regard. Only that, the last leap in its retrieval process should yield rules in Java expressions or predicates.   
  4. With some additional effort, this mechanism might fit streaming rules to browsers over any standard protocol such as WebSocket, HTTP/2, XMPP, MQTT. This method might even be clubbed together with Web-assembly to integrate secure, complex rules within web-browsers.

Getting Started:

Though it’s ideal to peek into the structure of an SDK before starting to work with it, we reverse the sequence for ease and simplicity. In this section, we illustrate, with simple problem statements or use-cases, how rules may be externalized.

Prerequisite

The consumers must have prior exposure to Software development with Java SE 1.8 or higher. That apart, a standard machine with Java SE 1.8 with an IDE is required. Throughout the article, Eclipse will be used as the IDE and MAVEN as the build tool across all illustrations. 

STEP-1:

Download the Library from here and keep it on your local path, E.g., D:\ externalize-rules.jar. Here is The full source codes.

STEP-2:

Create a Maven project with compiler source level set to 1.8 with the dependency as shown to the right.

PROBLEM STATEMENT:  A valued garment retail outlet is to offer discounts to its customers on different, frequent occasions with a varying set of criteria of edibility, such as occupation, income level, location, level of education, etc. To uncomplicate, we assume a simple customer model class – 

We further assume a class, Repo_Customer , which caters as the source of customers-information and picks customers qualifying for discount given a certain eligibility criterion. 

 

So long, it’s all usual; and we can define discount-eligibility rules using any one or a combination of the following:

STEP-3: It’s noteworthy that lambdas are less verbose and subject matter experts might define rules using these without having an in-depth knowledge of Java programming language.

We keep the discount rule outside the codebase since it might change frequently. And choose the simplest among all available options – we store the rules in a file on a local disk. The SDK helps loading these rules and executing them. The file below is stored on local disk:

We have created our own markup standard in the file (which can be whatever one designs and    implements and not restricted to any specific implementation):

   <RuleName><ColDelimiter><TargetModel><ColDelimter><LamdaExpression><RowDelimiter>

STEP-4:

Finally we write this small code to check our rules, to see if the rules execute :

Inside the SDK 

Now that we have successfully started and written a simple quick-start program, we can go back and start exploring what this SDK did, with illustrations. 

 

  1. Overall Package structure:
  2. com.yourcompany.libs.externalizedrules.poc.RuleExecutor<T, R>
    This is an abstract class which defines a rule execution method. This needs to be subclassed by consumer application code providing implementation for the two abstract methods.  While R denotes the result of a decision, T denotes the input object based on which the decision comes. For example, if we want to define a rule filtering out all customers aged above 60 years,  we need to subclass .RuleExecutor<DTO_Customer, Boolean>
  3. com.yourcompany.libs.externalizedrules.poc.models.RuleExecutionConfig
    This class loads the rules from a configuration source and must be initialized beforehand. This class takes care of the following –
    1. Loading raw rule base from configuration source
    2. Synthesizing java code from rule base snippet (E.g., Lamda)
    3. Compiling synthesized java code
    4. Finally loading the Class into main memory so that, the rule may be executed 

Concrete implementation for defined framework 

We already used PredicateRuleExecutor in [2]. This is a special implementation of com.yourcompany.libs.externalizedrules.poc.RuleExecutor<T, R>  which evaluates to a Boolean.

It performs the following 3 tasks:

  1. It loads rules that evaluate to a true or false. Which means, it translates the raw rule base or Lamda expression, to a java method which accepts an Object and returns a Boolean, i.e. forms a java.util.function.Predicate<java.lang.Object> .
  2. The framework, specifically PredicateExecutionContextLoader which subclasses RuleExecutionContextLoader, provides abstraction to these underlying tasks.
  3. Should one need to load encrypted and /or encoded / obfuscated series of bytes, according to some standard/customized codec, one must override the method,  com.yourcompany.libs.externalizedrules.poc.services.PredicateExecutionContextLoader.load(InputStream).
  4. One nice thing about this method is, it works at the byte. So, rules may be loaded from File system, URL, Cloud storage, database etc. 
  5. It loads the raw rules, from a local file. This method getConfigStream() returns an java.io.inputStream . It provides flexibility to load raw bytes from anywhere. 

We shall shortly illustrate how we can load rules from a few major and common sources.

Implementation for Some Common Sources

In this section we explore a few common but important sources where configuration can be loaded from. 

  1. From a Remote URL over HTTP
      
  2. An AWS S3 bucket
    To load rules from an S3 bucket, we need to make the following change only:

Putting pieces in right order

We have already seen the utility of the SDK coarsely as a PoC. However, the authors are in the process of contributing to shape it as an open-source project. In this section, which is the article’s last, we aim to highlight some of its salient features:

  • The framework works easily with different security frameworks (such as JASYPT) out of the box to ensure integrity and confidentiality of business rules so one can neither abuse clear-text business rules nor inject one’s own rule. 
  • Since, it’s vanilla java only, it perfectly fits all popular frameworks such as 
    • Spring and Spring BOOT
    • JSF
    • Play
    • ZK
  • It is a good fit for Spring Cloud Config without and with Cloud Bus.
  • Protocol neutrality makes it usable with any source on any cloud provider or on-premises store
  • One might implement one’s custom CODEC, too, on any cloud provider or on-premise storage. 
  • We can reload loaded configuration without application restart using JMX hooks.

About the Authors

Soham Sengupta has 16 years of experience split vertically across Academia, Research and Industry. A Master of Technology in Mobile Computing and Network Technology, he has been heading digital transformation for PAYBACK India. A sincere admirer of basic science, an avid lover of literature, he’s a passionate coder and enjoys sharing his ideas, which often turned out to be ahead-of-time, and thus innovative, on social platforms. More about the author may be found on his LinkedIn.

Srijeeb Roy has more than 23 years of experience in the IT industry. He holds a bachelor degree in Computer Science & Engineering from Jadavapur University, India. He has led the Java Center of Excellence (CoE) of Insurance Vertical of TCS in the past, and is currently focusing on various digital technology accelerators, which can help TCS customers to accelerate their digital journey. He has more than 20 years experience in Java/J2EE/JEE, Spring technologies and hybrid mobile app frameworks. He has written several articles on Java SE, EE and ME on Infoworld.com (previously JavaWorld.com) in the past

Rate this Article

Adoption
Style

BT