Validaterobot

Automatically Validate Business Rules Against a Library of Messages

Automatically Validate
Business Rules Against
a Library of Messages

Posted on: February 4, 2021

 

In most integrations, validating a library of messages against the schema is the first step - you will also need to validate against a set of business rules.

You may have a series of processes that generate LIXI2 messages for submitting to an API or you may host an API that consumes LIXI2 messages. The capability to automatically validate a set of messages with some business logic is likely needed.

I already showed (here) how to automatically validate a library of LIXI2 messages using our standards directly cloned from LIXILab.

In this blog post, I build upon the previous blog to include LIXI business rules validation of the LIXI2 messages. We fetch the latest standards, fetch a library of test messages, fetch some business rules (from LIXI Schematron Repository), and validate all the messages against both the latest standards and business rules.

Step 1. Create Folder and Clone Projects

Before starting, you need to have Python 3, have already installed the LIXI Python Package and have access to LIXILab.

Start this process by creating a folder called 'lixi-rules-validation-demo' - I've created this under the 'C:\temp\' directory.

Then, just like the previous tutorial, proceed to use the command or bash window to use the git clone command to clone both the LIXI2 schemas, LIXI2 samples and LIXI2 Schematron projects locally from LIXILab. If this is your first time running this command, you will be asked for your credentials for LIXILab. Notice that I have changed git clone command for schematron rules project slightly to clone into a 'rules' folder.

C:\temp\lixi-rules-validation-demo>git clone https://standards.lixi.org.au/lixi2/schemas.git
Cloning into 'schemas'...
remote: Enumerating objects: 319, done.
remote: Counting objects: 100% (319/319), done.
remote: Compressing objects: 100% (142/142), done.
Receiving objects: 100% (2850/2850), 10.47 MiB | 1.13 MiB/sving objects:  99% (2849/2850), 10.47 MiB | 1.13 MiB/s
Receiving objects: 100% (2850/2850), 10.73 MiB | 1.19 MiB/s, done.
Resolving deltas: 100% (2667/2667), done.
Updating files: 100% (802/802), done.

C:\temp\lixi-rules-validation-demo>

C:\temp\lixi-rules-validation-demo>git clone https://standards.lixi.org.au/lixi2/samples.git
Cloning into 'samples'...
remote: Enumerating objects: 2748, done.
remote: Counting objects: 100% (2748/2748), done.
remote: Compressing objects: 100% (689/689), done.
remote: Total 2748 (delta 2089), reused 2705 (delta 2052)
Receiving objects: 100% (2748/2748), 1.15 MiB | 1.30 MiB/s, done.
Resolving deltas: 100% (2089/2089), done.

C:\temp\lixi-rules-validation-demo>

C:\temp\lixi-rules-validation-demo>git clone https://standards.lixi.org.au/lixi2/schematron-demo.git rules/
Cloning into 'rules'...
warning: redirecting to https://standards.lixi.org.au/lixi2/schematron-demo.git/
remote: Enumerating objects: 5404, done.
remote: Counting objects: 100% (5404/5404), done.
remote: Compressing objects: 100% (508/508), done.
remote: Total 5404 (delta 4880), reused 5399 (delta 4875)
Receiving objects: 100% (5404/5404), 5.59 MiB | 1.25 MiB/s, done.
Resolving deltas: 100% (4880/4880), done.

C:\temp\lixi-rules-validation-demo>

 

Step 2. Copy the Python Code into a New File

In the new folder create an empty file called validate_rules_standalone_script.py and copy the code from the block at the bottom of this page into the file and save it.

After completing this, you will have two sub-directories and a single python script.

└── lixi-rules-validation-demo
    ├── rules
    ├── samples
    ├── schemas
    └── validate_rules_standalone_script.py

Step 3. Run the Python Script

Depending on your Python installation, you can now run the script - you could use an IDE such as vsCode or execute the script from a command or bash session. For example, you can run it at the Windows CMD prompt as follows.

C:\temp\lixi-rules-validation-demo>python validate_rules_standalone_script.py
Validating 214 files.
Successfully Validated 214 files.
Failed to Validate 0
done

C:\temp\lixi-rules-validation-demo>

 

Step 4. What Next? Extend the rules of course!

This is just a demonstration of how you might plug business rules validation with the help of LIXI2 on your journey to automate your software delivery lifecycle.

The same rules can be extended to cater your organization's unique business rules. Or you can help expand the general message business rules with your contribution at Schematron Library of Business Rules project in LIXILab.

Python Code to Save in 'validate_rules_standalone_script.py'

import glob, os, lixi

# Retrieve this scripts path
this_path = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))

# Derive the path to the cloned schemas
schema_path = os.path.join(this_path, 'schemas','xsd')

# Derive the path to the cloned rules
rules_path = os.path.join(this_path, 'rules','schematron')

# Derive the path to the cloned samples
glob_search_string = os.path.join(this_path, 'samples','Samples') +'/**/*.xml'

# Set the schema folder path in the lixi library
lixi.set_schema_folder(schema_path)

# Ininitalise a list of valid files
valid_file_list = []

# Ininitalise a dictionary of invalid files to store the error
invalid_file_dict = {}

# Create a list of files to validate
files_to_check = glob.glob(glob_search_string , recursive=True)

# Print the number of files that are found to be validated
print('Validating ' + str(len(files_to_check)) + ' files.')

# Loop through the files
for filepath in files_to_check:
    try:
        # Validate each message with the LIXI Library
        xml_obj = lixi.read_message(message_path=filepath)
        
        # Obtain standard to get the correct schematron business rules path
        standard = xml_obj.lixi_transaction_type

        # Validate each message with the LIXI Business Rules
        valid, message, logs = xml_obj.validate_schematron(schematron_schema_path=os.path.join(rules_path, standard+" Schematron Rule.sch"))
        
        if valid:
           # If successful, add the file path to the list of valid files
           valid_file_list.append(filepath)
        else:
           # If business rule validation fails, add the file path to the dictionary of invalid files with the error(s)
           invalid_file_dict[filepath] = message        

    except Exception as e:

        # If validation fails, add the file path to the dictionary of invalid files with the error
        if str(e.__class__.__name__) == 'LIXIValidationError':
           invalid_file_dict[filepath] = e.error_log
        elif  str(e.__class__.__name__) == 'LIXIInvalidSyntax':
           invalid_file_dict[filepath] = e
        elif  str(e.__class__.__name__) == 'LIXIResouceNotFoundError':
            invalid_file_dict[filepath] = e

print('Succesfully Validated ' + str(len(valid_file_list)) + ' files.')
print('Failed to Validate ' + str(len(invalid_file_dict)))

# Loop through the dictionary of invalid file and print the details
for invalid_file, invalid_file_error_log in invalid_file_dict.items():
    print ('Filename : ' + invalid_file)
    if type(invalid_file_error_log).__name__ in('LIXIInvalidSyntax', 'LIXIResouceNotFoundError'):
        print('Error: ' + invalid_file_error_log.args[0].strip())
    if type(invalid_file_error_log).__name__ in('str'):
        print('Error: ' + invalid_file_error_log.strip())
    else:
        for error_item in invalid_file_error_log: 
            print(error_item.message_location.strip())
            print(error_item.message.strip())
            
print('done')

Related Blogs


Written by:
Shane Rigby, LIXI Limited CEO
First Published: February 4, 2021