Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
ttrapp
Active Contributor

In this blog I sketch a solution for comparing BRFplus rule systems. I’ll discuss the use case and I would be interested in your feedback. Also I would like to know whether other people are working on the same topic and would like to exchange source code. Maybe this could lead to the first open source project in the area of BRFplus.

Use Cases

At first I think that comparison of objects like different rule systems is a value in itself because the concept of equality resp. inequality is one of most profound ones I know in philosophy and mathematics. But there are also more business cases:

  • In larger development projects sometimes rule set are shipped which contain an implementation of decision logic. Often they are shipped as implementation accelerators, used for tests and are altered afterwards.
  • Sometimes people don’t want to change a rule system and copy it instead, do some changes, test it, and ship it after that. Then a comparison is useful.
  • Rule systems are generated/changed using metadata and the BRFplus API. You want to check the results by comparing them.

Let us look at the first described scenario. I develop rule systems that have be to compliant to legislation and shipped to different organizations as applications of storage type system. These implementations are mostly stable due to compliance reasons and there one is only allowed to change them minimally and only in certain parts. Usually business experts use my rule systems as template and copy and alter it. Later the comparison is useful to control what has been changed:

  • A revisior or auditor wants to analyze the adaptations.
  • If a have to change my template application (because it contained an error or legislation changed) a comparison after the import is helpful when the copied rule system has to be changed.
  • Sometimes organizations evolved the rule systems in a different way. Now they want to check the difference and perform harmonization or even want to implement a common version.

So please let me summarize: comparison of different rule systems can be part of a usual maintenance and evolution process. It becomes necessary if you have a couple of organizations that have rule systems that are quite similar and evolved from the same template of decision logic. But there are other use cases when comparison of decision logic is useful.

The Challenge

Comparing two rule systems is difficult. BRFplus has only functions for comparing two rule set versions. The transaction FDT_HELPERS contains a report that checks whether two versions are identical. This is useful if you want to check whether a transport was (successfully) imported into a system. But it is not that useful for our purposes.

So we need to develop a solution by ourselves. The challenge is that BRFplus does have an object oriented API but provides no simple textual representation of the rules. But there are more problems: we have to define when two BRFplus artifacts are identical:

  • Are two objects different if their technical name is different? If you allow that the technical can be different – how do you identify corresponding BRFplus entities that you want to compare?
  • Which metadata should be considered or not considered in the comparison? The information which user performed the change and the specific time should not matter for example.
  • Should the flag whether a rule set is active or not active be considered in the comparison? This depends on the use case: when you deliver a rule set assigned to a BRFplus function as template, then it is likely that it is not enabled. In this case, the user copies the rule set, sets it to active and perhaps alters it.

This shows the following: the comparison of two BRFplus applications is no trivial task and depends on the scenario i.e. the way that a rule system is copied and changed when working with a template. So I came to the conclusion that it would be useful to have a library with different utility functions.

My Approach

After some experiments with the BRFplus API it became clear that this is not the right tool for comparisons. I also learned the especially the structure of the rules is very complex and they are hard to compare. Moreover I decided that a need a flexible toolset that would allow different kinds of comparisons.

My solution uses the XML representation of an BRFplus application. This representation is far from being readable. When you look at the structure of an XML document you will see that it contains on different artifacts which can be seen in the picture below. The most important entity is the expression which are grouped as elements FDTNS:EXPRESSION and are identified using IDs. More complex objects like conditions of rules refer to expressions by their IDs.

So f.e. a rule consists of conditions which are in fact expressions. In the XML representation the ID is stored and the expression with this ID is stored somewhere else in the XML document.

If you want to compare two BRFplus entities (f.e. two rules) one approach is to replace each occurrence of its expressions (think of a condition defined by its ID) with the content of the corresponding XML element which is stored in another part of the XML representation. If you do this in recursive way you will “expand” the BRFplus entity to a tree containing all relevant in expressions. This can be done easily using an iteration of the following XSL transformation which can be performed using the CALL TRANSFORMATION command in ABAP:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version=
"1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:FDTNS="http://sap.com/fdt/transport">
  <xsl:output method=
"xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:strip-space elements=
"*"/>

  <xsl:template match=
"node() | @*">
    <xsl:copy>
      <xsl:apply-templates select=
"node() | @*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match=
"FDTNS:RULES/FDTNS:item/FDTNS:RULE_ID |
                      FDTNS:EXPRESSION_ID |
                      FDTNS:CONDITION |
                      /FDTNS:FDT/FDTNS:RULESET/FDTNS:COND_RANGE/FDTNS:PARAMETER_ID">
    <xsl:variable name=
"id" select="string(.)"/>
    <xsl:choose>
      <xsl:when test=
"count(/FDTNS:FDT/FDTNS:EXPRESSION[FDTNS:ADMIN_DATA/FDTNS:ID/text()=$id])>0">
        <xsl:copy-of select=
"/FDTNS:FDT/FDTNS:EXPRESSION[FDTNS:ADMIN_DATA/FDTNS:ID/text()=$id]"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select=
"node() | @*"
/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:transform>

If you have now a rule that is copied from another rule and both are using the same data elements then you compare them using a simple string compare. But before you have to remove the administration data since timestamps, change user and so will be always different. This can be done using the following transformation:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version=
"1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 
xmlns:FDTNS="http://sap.com/fdt/transport">
  <xsl:output method=
"xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:strip-space elements=
"*"/>

  <xsl:template match=
"node() | @*">
    <xsl:copy>
      <xsl:apply-templates select=
"node() | @*"/>
    </xsl:copy>
    </xsl:template>

  <xsl:template match=
"FDTNS:ADMIN_DATA"/> <!-- Don't copy this element -->

</xsl:transform>


Another important operation for the above mentioned string comparison is the extraction. This can be performed also in XML. Here I show how to extract a certain rule in a rule set using XSLT:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:FDTNS="http://sap.com/fdt/transport">
  <xsl:param name=
"POSITION"/>
  <xsl:output method=
"xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:strip-space elements=
"*"/>

  <xsl:template match=
"/">
    <xsl:copy-of

select="/FDTNS:RULESET/FDTNS:RULES/FDTNS:item[string(FDTNS:POSITION)=string($POSITION)]"/>
  </xsl:template>
</xsl:transform>

Using those transformations you can “expand” two applications, remove administration data, extract parts and compare them using string comparison.

And this is what I implemented and tested successfully.

Summary

I discussed some use cases for rule system comparison and described the main ideas of my implementation. Now I have following questions for the BRFplus community:

  • Is someone working on the same problem?
  • Are there other approaches?
  • If someone is working on the same approach, is there interest in sharing the source? Maybe we could start an Open Source project by combining our source code.
Labels in this area